home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / MacPerl ƒ / Perl Source ƒ / MacPerl / MPAppleEvents.c < prev    next >
Text File  |  1994-01-02  |  138KB  |  5,398 lines

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Real Perl Application
  3. File        :    MPAppleEvents.c    -
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Started    :    17Mar93                                Language    :    MPW C
  10. Modified    :    29May93    MN    Compiles correctly
  11.                 30May93    MN    Support console Windows
  12.                 16Aug93    MN    DoScript
  13.                 28Aug93    MN    FormatCommand
  14. Last        :    28Aug93
  15. *********************************************************************/
  16.  
  17. #include <AppleEvents.h>
  18. #include <Sysequ.h>
  19. #include <Menus.h>
  20. #include <PLStringFuncs.h>
  21. #include <Scrap.h>
  22. #include <TextEdit.h>
  23. #include <AEObjects.h>
  24. #include <AEPackObject.h>
  25. #include <AERegistry.h>
  26. #include <Resources.h>
  27. #include <String.h>
  28. #include <TFileSpec.h>
  29.  
  30. #include "MPGlobals.h"
  31. #include "MPUtils.h"
  32. #include "MPAEUtils.h"
  33. #include "MPWindow.h"
  34. #include "MPFile.h"
  35. #include "MPAppleEvents.h"
  36. #include "MPScript.h"
  37. #include "MPSave.h"
  38. #include "MPPreferences.h"
  39.  
  40. /* these should come from the registry */
  41.  
  42. #define         kAEStartedRecording  'rec1'
  43. #define         kAEStoppedRecording    'rec0'
  44. #define         kAEDontExecute         0x00002000
  45.  
  46. #define         pText                     'TEXT'
  47. #define     cSpot                 'cspt'
  48.  
  49. /*
  50.     Text Properties
  51. */
  52.  
  53. #define         pStringWidth            'pwid'
  54.  
  55. /*
  56.     Window Properties - See the Registry for Details
  57. */
  58.  
  59. #define     pPosition               'ppos'
  60. #define         pPageSetup                'PSET' /* One of ours - Not in registry */
  61. #define         pShowBorders            'PBOR' /* Another of ours */
  62.  
  63. #define         typeTPrint                'TPNT' /* A raw TPrint record - also one of ours */
  64.  
  65. /*
  66.     Error Codes
  67. */
  68.  
  69. #define         kAEGenericErr    -1799
  70.  
  71. static short   gBigBrother;
  72. static char    *gTypingBuffer;
  73. static short   gCharsInBuffer;
  74. static AEDesc  gTypingTargetObject;
  75.  
  76. pascal Boolean AllSelected(TEHandle te)
  77. {
  78.     return ((*te)->selStart == 0 && (*te)->selEnd == (*te)->teLength);
  79. }
  80.  
  81. #ifndef RUNTIME
  82.  
  83. /*-----------------------------------------------------------------------*/
  84. /**----------                         APPLE EVENT HANDLING         ---------------**/
  85. /*-----------------------------------------------------------------------*/
  86.  
  87. pascal OSErr GetTHPrintFromDescriptor(const AEDesc *sourceDesc, THPrint *result)
  88. {
  89.     OSErr   myErr;
  90.     Size    ptSize;
  91.     AEDesc  resultDesc;
  92.  
  93.     *result = nil;
  94.  
  95.     if (myErr = AECoerceDesc(sourceDesc,typeTPrint,&resultDesc))
  96.         return myErr;
  97.  
  98.     *result = (THPrint)NewHandle(sizeof(TPrint));
  99.  
  100.     PrOpen();
  101.     PrintDefault(*result);
  102.  
  103.     HLock((Handle)*result);
  104.  
  105.     GetRawDataFromDescriptor(&resultDesc, (Ptr)**result, sizeof(TPrint), &ptSize);
  106.  
  107.     HUnlock((Handle)*result);
  108.  
  109.     if ((ptSize<sizeof(TPrint)) || (PrValidate(*result))) {
  110.         myErr = errAECoercionFail;
  111.         DisposHandle((Handle)*result);
  112.         *result = nil;
  113.     }
  114.  
  115.     PrClose();
  116.  
  117.     if (resultDesc.dataHandle)
  118.         AEDisposeDesc(&resultDesc);
  119.  
  120.     return myErr;
  121. } /*GetTHPrintFromDescriptor*/
  122.  
  123. /*******************************************************************************/
  124. /*
  125.     Object Accessors - Utility Routines
  126. */
  127.  
  128. #pragma segment ObjectAccessors
  129.  
  130. /*
  131.     Returns the WindowPtr of the window with title nameStr
  132.     or nil if there is no matching window.
  133. */
  134. pascal WindowPtr WindowNameToWindowPtr(StringPtr nameStr)
  135. {
  136.     WindowPtr theWindow;
  137.     Str255    windTitle;
  138.  
  139.     theWindow = (WindowPtr)*((Handle)WindowList);
  140.     /*
  141.         iterate through windows - we use WindowList 'cos we could
  142.         have made the window invisible and  we lose it - so we
  143.         can't set it back to visible!!
  144.     */
  145.     while (theWindow) {
  146.         GetWTitle(theWindow, windTitle);
  147.         if (EqualString(windTitle,
  148.                              nameStr,
  149.                                         false,
  150.                                         true))     /* ignore case, don't ignore diacriticals */
  151.             return theWindow;
  152.       theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  153.     }
  154.  
  155.     return theWindow;
  156. }    /* WindowNameToWindowPtr */
  157.  
  158. pascal WindowPtr GetWindowPtrOfNthWindow(short index)
  159. /* returns a ptr to the window with the given index
  160.   (front window is 1, behind that is 2, etc.).  if
  161.   there's no window with that index (inc. no windows
  162.   at all), returns nil.
  163. */
  164. {
  165.   WindowPtr theWindow;
  166.  
  167.     theWindow = (WindowPtr)*((Handle)WindowList);
  168.  
  169.     /* iterate through windows */
  170.  
  171.     while (theWindow) {
  172.         if (--index <= 0)
  173.             return theWindow;
  174.  
  175.       theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  176.     }
  177.  
  178.     return nil;
  179. }    /* GetWindowPtrOfNthWindow */
  180.  
  181. pascal short CountWindows(void)
  182. {
  183.     WindowPtr theWindow;
  184.     short     index;
  185.  
  186.     index = 0;
  187.     theWindow = (WindowPtr)*((Handle)WindowList);
  188.  
  189.     /* iterate through windows */
  190.  
  191.     while (theWindow) {
  192.         index++;
  193.         theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  194.     }
  195.  
  196.     return index;
  197. } /*CountWindows*/
  198.  
  199. #endif
  200.  
  201. /**-----------------------------------------------------------------------
  202.         Name:         DoOpenApp
  203.         Purpose:        Called on startup, creates a new document.
  204.     -----------------------------------------------------------------------**/
  205.  
  206. #pragma segment Main
  207.  
  208. pascal OSErr DoOpenApp(const AppleEvent *message, AppleEvent *reply, long refcon)
  209. {
  210.     if (gRuntimeScript)
  211.         return DoScript(message, reply, refcon);
  212.  
  213.     return noErr;
  214. }
  215.  
  216. /**-----------------------------------------------------------------------
  217.         Name:         DoOpenDocument
  218.         Purpose:        Open all the documents passed in the Open AppleEvent.
  219. -----------------------------------------------------------------------**/
  220.  
  221. #pragma segment Main
  222.  
  223. pascal OSErr DoOpenDocument(const AppleEvent *message, AppleEvent *reply, long refcon)
  224. {
  225.     long        index;
  226.     long        itemsInList;
  227.     AEKeyword   keywd;
  228.     OSErr       err;
  229.     OSErr       ignoreErr;
  230.     AEDescList  docList;
  231.     long        actSize;
  232.     DescType    typeCode;
  233.     FSSpec      theFSSpec;
  234.     EventRecord    ev;
  235.     DocType        type;
  236.  
  237.     if (gRuntimeScript)
  238.         return DoScript(message, reply, refcon);
  239.     
  240.     /* open the specified documents */
  241.  
  242.     docList.dataHandle = nil;
  243.  
  244.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  245.  
  246.     if (err==noErr)
  247.         err = AECountItems( &docList, &itemsInList) ;
  248.     else
  249.       itemsInList = 0;
  250.  
  251.     if (itemsInList) {
  252.         err =
  253.             AEGetNthPtr(&docList, 1, typeFSS, &keywd, &typeCode, (Ptr)&theFSSpec, sizeof(theFSSpec), &actSize);
  254.         
  255.         if (!err) {
  256.             type = GetDocType(&theFSSpec);
  257.             
  258.             GetNextEvent(0, &ev);
  259.         
  260.             switch (type) {
  261.             case kPlainTextDoc:
  262.             case kOldRuntime6Doc:
  263.             case kRuntime6Doc:
  264.             case kRuntime7Doc:
  265.                 if (!(ev.modifiers & optionKey) != gPerlPrefs.runFinderOpens)
  266.                     break;
  267.                 if (refcon != -1)
  268.                     break;
  269.                     
  270.                 err = DoScript(message, reply, 0);
  271.                     
  272.                 goto done;
  273.             }
  274.         }
  275.     }
  276.  
  277.     for (index = 1; index <= itemsInList; index++)
  278.         if (err==noErr) {
  279.             err = AEGetNthPtr( &docList, index, typeFSS, &keywd, &typeCode,
  280.                                                  (Ptr)&theFSSpec, sizeof(theFSSpec), &actSize ) ;
  281.             if (err==noErr)
  282.                 switch (type = GetDocType(&theFSSpec)) {
  283.                 case kPlainTextDoc:
  284.                 case kOldRuntime6Doc:
  285.                 case kScriptDoc:
  286.                 case kRuntime6Doc:
  287.                 case kRuntime7Doc:
  288.                       err = OpenOld(theFSSpec, type);
  289.                     break;
  290.                 case kPreferenceDoc:
  291.                     OpenPreferenceFile(&theFSSpec);
  292.                     break;
  293.                 }
  294.         }
  295.  
  296. done:    
  297.   if (docList.dataHandle)
  298.         ignoreErr = AEDisposeDesc(&docList);
  299.  
  300.     return err;
  301. }
  302.  
  303. /**-----------------------------------------------------------------------
  304.         Name:         MyQuit
  305.         Purpose:        Quit event received- exit the program.
  306.     -----------------------------------------------------------------------**/
  307.  
  308. #pragma segment Main
  309.  
  310. pascal OSErr MyQuit(const AppleEvent *message, const AppleEvent *reply, long refcon)
  311. {
  312. #pragma unused (reply,refcon)
  313.  
  314.     DescType saveOpt;
  315.     OSErr    tempErr;
  316.     OSErr    myErr;
  317.     DescType returnedType;
  318.     long     actSize;
  319.  
  320.     saveOpt = kAEAsk; /* the default */
  321.     tempErr = AEGetParamPtr(message,
  322.                                     keyAESaveOptions,
  323.                                     typeEnumerated,
  324.                                     &returnedType,
  325.                                     (Ptr)&saveOpt,
  326.                                     sizeof(saveOpt),
  327.                                     &actSize);
  328.  
  329.     if (saveOpt != kAENo)
  330.         myErr = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
  331.  
  332.     if (myErr == noErr)
  333.         DoQuit(saveOpt);
  334.  
  335.     return myErr;
  336. }
  337.  
  338. /**-----------------------------------------------------------------------
  339.         Name:         DoAppleEvent
  340.         Purpose:        Process and despatch the AppleEvent
  341.     -----------------------------------------------------------------------**/
  342.  
  343. #pragma segment Main
  344.  
  345. pascal void DoAppleEvent(EventRecord theEvent)
  346. {
  347.   OSErr err;
  348.  
  349.   /*should check for your own event message types here - if you have any*/
  350.  
  351.     err = AEProcessAppleEvent(&theEvent);
  352. }
  353.  
  354. #ifndef RUNTIME
  355.  
  356. /**-----------------------------------------------------------------------
  357.         Name:         MakeSelfAddress
  358.         Purpose:        Builds an AEAddressDesc for the current process
  359.     -----------------------------------------------------------------------**/
  360.  
  361. pascal OSErr MakeSelfAddress(AEAddressDesc *selfAddress)
  362. {
  363.   ProcessSerialNumber procSerNum;
  364.  
  365.     procSerNum.highLongOfPSN = 0;
  366.     procSerNum.lowLongOfPSN  = kCurrentProcess;
  367.  
  368.     return
  369.         AECreateDesc(
  370.             typeProcessSerialNumber,
  371.             (Ptr)&procSerNum,
  372.             sizeof(procSerNum),
  373.             selfAddress);
  374. } /* MakeSelfAddress */
  375.  
  376. #endif
  377.  
  378. /**--------------------------------------------------------------------
  379.     Name :         SendAESetObjProp
  380.     Function :     Creates a property object from an object,
  381.                     a property type and its data and sends it to
  382.                     the requested address, and cleans up zapping params too
  383.     --------------------------------------------------------------------**/
  384.  
  385. pascal OSErr SendAESetObjProp(
  386.     AEDesc        *theObj,
  387.     DescType      theProp,
  388.     AEDesc        *theData,
  389.     AEAddressDesc *toWhom)
  390. {
  391.     AEDesc     propObjSpec;
  392.     AppleEvent myAppleEvent;
  393.     AppleEvent defReply;
  394.     OSErr      myErr;
  395.     OSErr      ignoreErr;
  396.     AEDesc     theProperty;
  397.  
  398.     /* create an object spec that represents the property of the given object */
  399.  
  400.     myErr = AECreateDesc(typeType, (Ptr)&theProp, sizeof(theProp), &theProperty);
  401.     if (myErr==noErr)
  402.         myErr =
  403.             CreateObjSpecifier(
  404.                 cProperty,
  405.                 theObj,
  406.                 formPropertyID,
  407.                 &theProperty,
  408.                 true,
  409.                 &propObjSpec);
  410.  
  411.     /* create event */
  412.  
  413.     if (myErr==noErr)
  414.         myErr =
  415.             AECreateAppleEvent(
  416.                 kAECoreSuite,
  417.                 kAESetData,
  418.                 toWhom,
  419.                 0,
  420.                 0,
  421.                 &myAppleEvent);
  422.  
  423.     /* add prop obj spec to the event */
  424.  
  425.     if (myErr==noErr)
  426.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &propObjSpec);
  427.  
  428.     /* add prop data to the event */
  429.  
  430.     if (myErr==noErr)
  431.         myErr = AEPutParamDesc(&myAppleEvent, keyAEData, theData);
  432.  
  433.     /* send event */
  434.  
  435.     if (myErr==noErr)
  436.         myErr =
  437.             AESend(
  438.                 &myAppleEvent,
  439.                 &defReply,
  440.                 kAENoReply+kAEAlwaysInteract,
  441.                 kAENormalPriority,
  442.                 kAEDefaultTimeout,
  443.                 nil,
  444.                 nil);
  445.  
  446.     if (myAppleEvent.dataHandle)
  447.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  448.  
  449.     if (&propObjSpec.dataHandle)
  450.       ignoreErr = AEDisposeDesc(&propObjSpec);
  451.  
  452.     if (theData->dataHandle)
  453.         ignoreErr = AEDisposeDesc(theData);
  454.  
  455.     if (toWhom->dataHandle)
  456.         ignoreErr = AEDisposeDesc(toWhom);
  457.  
  458.     return myErr;
  459. }    /* SendAESetObjProp */
  460.  
  461. /*----------------------------------------------------------------------------------------------*/
  462. /*
  463.     Private AEObject definitions
  464. */
  465. #pragma segment AECommandHandlers
  466.  
  467. #define typeMyAppl       'BAPP'    /* sig of my private token type for the app     - appToken   */
  468. #define typeMyWndw         'BWIN'    /* sig of my private token type for windows     - windowToken   */
  469. #define typeMyText           'BTXT'    /* sig of my private token type for text        - textToken     */
  470. #define typeMyTextProp   'BPRP'    /* sig of my private token type for text properties    - textPropToken */
  471. #define typeMyWindowProp 'WPRP'    /* sig of my private token type for window properties  - windowPropToken */
  472. #define typeMyApplProp   'APRP'    /* sig of my private token type for appl properties    - applPropToken */
  473. #define typeMyMenu       'MTKN'    /* sig of my private token type for menus       - menuToken  */
  474. #define typeMyMenuItem   'ITKN'    /* sig of my private token type for menus       - menuItemToken  */
  475. #define typeMyMenuProp   'MPRP'    /* sig of my private token type for menu properties - menuPropToken  */
  476. #define typeMyItemProp   'IPRP'    /* sig of my private token type for menu item properties  - menuItemPropToken  */
  477.  
  478. /* These are entirely private to our app - used only when resolving the object specifier */
  479.  
  480. typedef    ProcessSerialNumber appToken;
  481.  
  482. struct applPropToken{
  483.     appToken tokenApplToken;
  484.     DescType tokenApplProperty;
  485. };
  486.  
  487. typedef struct applPropToken applPropToken;
  488.  
  489. typedef    WindowPtr WindowToken;
  490.  
  491. struct windowPropToken{
  492.         WindowToken tokenWindowToken;
  493.         DescType    tokenProperty;
  494.     };
  495.  
  496. typedef struct windowPropToken windowPropToken;
  497.  
  498. struct TextToken{
  499.         WindowPtr tokenWindow;
  500.         short     tokenOffset;
  501.         short     tokenLength;
  502.     };
  503.  
  504. typedef struct TextToken TextToken;
  505.  
  506. struct textPropToken{
  507.         TextToken propertyTextToken;
  508.         DescType  propertyProperty;
  509.     };
  510.  
  511. typedef struct textPropToken textPropToken;
  512.  
  513. /* Tokens related to menus */
  514.  
  515. struct MenuToken {
  516.     MenuHandle theTokenMenu;
  517.     short      theTokenID;
  518. };
  519.  
  520. typedef struct MenuToken MenuToken;
  521.  
  522. struct MenuItemToken {
  523.     MenuToken  theMenuToken;
  524.     short      theTokenItem;
  525. };
  526.  
  527. typedef struct MenuItemToken MenuItemToken;
  528.  
  529. struct MenuPropToken {
  530.     MenuToken  theMenuToken;
  531.     DescType   theMenuProp;
  532. };
  533.  
  534. typedef struct MenuPropToken MenuPropToken;
  535.  
  536. struct MenuItemPropToken {
  537.     MenuItemToken  theItemToken;
  538.     DescType       theItemProp;
  539. };
  540.  
  541. typedef struct MenuItemPropToken MenuItemPropToken;
  542.  
  543. #ifndef RUNTIME
  544.  
  545. /*
  546.     Name: GotRequiredParams
  547.     Function: Checks all parameters defined as 'required' have been read
  548. */
  549. pascal OSErr GotRequiredParams(const AppleEvent *theAppleEvent)
  550. {
  551.     OSErr    myErr;
  552.     DescType returnedType;
  553.     Size     actSize;
  554.  
  555.     /* look for the keyMissedKeywordAttr, just to see if it's there */
  556.  
  557.     myErr =
  558.         AEGetAttributePtr(
  559.             theAppleEvent,
  560.             keyMissedKeywordAttr,
  561.             typeWildCard,
  562.             &returnedType,
  563.             nil,
  564.             0,
  565.             &actSize);
  566.  
  567.     if (myErr == errAEDescNotFound)
  568.         return noErr;            /* attribute not there means we got all req params */
  569.     else
  570.         if (myErr == noErr)
  571.             return errAEParamMissed;        /* attribute there means missed at least one */
  572.         else
  573.             return myErr;        /* some unexpected arror in looking for the attribute */
  574. }    /* GotReqiredParams */
  575.  
  576. /**--------------------------------------------------------------------
  577.     Name : SetSelectionOfAppleEventDirectObject
  578.     Function : Resolves the Direct Object into a text token and
  579.                          sets the selection of the specified document to that
  580.                          specified in the direct object.
  581.                          Returns the doc and TEHandle chosen.
  582.     --------------------------------------------------------------------**/
  583.  
  584. pascal OSErr SetSelectionOfAppleEventDirectObject(
  585.     const AppleEvent *theAppleEvent,
  586.     DPtr             *theDocument,
  587.     TEHandle         *theHTE)
  588. {
  589.     OSErr     myErr;
  590.     DescType  returnedType;
  591.     long      actSize;
  592.     TextToken myTextToken;
  593.     OSErr     paramErr;
  594.     WindowPtr fWin;
  595.  
  596.     paramErr =
  597.         AEGetParamPtr(
  598.             theAppleEvent,
  599.             keyDirectObject,
  600.             typeMyText,
  601.             &returnedType,
  602.             (Ptr)&myTextToken,
  603.             sizeof(myTextToken),
  604.             &actSize);
  605.  
  606.     myErr = GotRequiredParams(theAppleEvent);
  607.  
  608.     /* now let's work on the direct object, if any */
  609.  
  610.     if (paramErr == errAEDescNotFound) {
  611.         /* no direct object; check we have a window */
  612.  
  613.         fWin = FrontWindow();
  614.  
  615.         if (fWin == nil)
  616.             return -1700; /* Generic Err */
  617.  
  618.         *theDocument = DPtrFromWindowPtr(fWin);
  619.         *theHTE      = (*theDocument)->theText;
  620.     }
  621.  
  622.     if (paramErr == noErr)  {
  623.         /* got a text token */
  624.  
  625.         *theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  626.         *theHTE      = (*theDocument)->theText;
  627.  
  628.         TESetSelect(
  629.             myTextToken.tokenOffset-1,
  630.             myTextToken.tokenOffset+myTextToken.tokenLength-1,
  631.             *theHTE);
  632.  
  633.     }
  634.  
  635.     if ((paramErr!=noErr) &&
  636.          (paramErr!=errAEDescNotFound)
  637.     ) {
  638.          *theDocument = DPtrFromWindowPtr(FrontWindow());
  639.          *theHTE      = (*theDocument)->theText;
  640.      }
  641.  
  642.     return myErr;
  643.  
  644. } /* SetSelectionOfAppleEventDirectObject */
  645.  
  646. /**--------------------------------------------------------------------
  647.     Name             : SetSelectionOfAppleEventObject
  648.     Function     : Resolves the whatObject type of the AppleEvent into a text
  649.                       token and sets the selection to be that specified in the
  650.                       text token.
  651.                       Returns the doc and TEHandle chosen.
  652.     --------------------------------------------------------------------**/
  653.  
  654. pascal OSErr SetSelectionOfAppleEventObject(
  655.     OSType            whatObject,
  656.     const AppleEvent *theAppleEvent,
  657.     DPtr             *theDocument,
  658.     TEHandle         *theHTE)
  659. {
  660.     DescType   returnedType;
  661.     long       actSize;
  662.     TextToken  myTextToken;
  663.     OSErr      paramErr;
  664.  
  665.     paramErr  =
  666.         AEGetParamPtr(
  667.             theAppleEvent,
  668.             whatObject,
  669.             typeMyText,
  670.             &returnedType,
  671.             (Ptr)&myTextToken,
  672.             sizeof(myTextToken),
  673.             &actSize);
  674.  
  675.     if (paramErr == noErr) {
  676.         /* got a text token */
  677.  
  678.         *theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  679.         *theHTE      = (*theDocument)->theText;
  680.  
  681.         TESetSelect(
  682.             myTextToken.tokenOffset-1,
  683.             myTextToken.tokenOffset+myTextToken.tokenLength-1,
  684.             *theHTE);
  685.     }
  686.  
  687.     return paramErr;
  688. } /* SetSelectionOfAppleEventObject */
  689.  
  690. #endif
  691.  
  692. pascal void EnforceMemory(DPtr theDocument, TEHandle theHTE)
  693. {
  694.     if (theDocument->kind != kDocumentWindow && (*theHTE)->teLength > theDocument->u.cons.memory) {
  695.         short    obulus =    (*theHTE)->teLength - theDocument->u.cons.memory;
  696.         short saveStart;
  697.         short    saveEnd;
  698.         Ptr    search = *(*theHTE)->hText;
  699.         short rest   = theDocument->u.cons.memory;
  700.         
  701.         while (search[obulus-1] != '\n' && rest--)
  702.             ++obulus;
  703.             
  704.         saveStart    =    (*theHTE)->selStart - obulus;
  705.         saveEnd        =    (*theHTE)->selEnd      - obulus;
  706.         
  707.         TESetSelect(0, obulus, theHTE);
  708.         TEDelete(theHTE);
  709.         TESetSelect(saveStart < 0 ? 0 : saveStart, saveEnd < 0 ? 0 : saveEnd, theHTE);
  710.         
  711.         if (theDocument->u.cons.fence < 32767)
  712.             theDocument->u.cons.fence    -=    obulus;
  713.     }
  714. }
  715.  
  716. #ifndef RUNTIME
  717.  
  718. /* -----------------------------------------------------------------------
  719.         Name:         DoCopyEdit
  720.         Purpose:        Performs a copy text operation on the text selection specified
  721.                         by the appleEvent direct object (if any)
  722.      -----------------------------------------------------------------------**/
  723.  
  724. pascal OSErr DoCopyEdit(const AppleEvent *theAppleEvent,AppleEvent *reply, long refCon)
  725. {
  726. #pragma unused (reply,refCon)
  727.  
  728.     OSErr    myErr;
  729.     TEHandle theHTE;
  730.     DPtr     theDocument;
  731.  
  732.     /*
  733.             Here we extract the information about what to copy from the
  734.             directObject - if any
  735.     */
  736.  
  737.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent,&theDocument,&theHTE))
  738.         return myErr;
  739.  
  740.     myErr = (OSErr) ZeroScrap();
  741.     TECopy(theHTE);
  742.     TEToScrap();
  743.  
  744.     if (myErr)
  745.         return myErr;
  746.  
  747.     if (!SetSelectionOfAppleEventObject(
  748.         keyAEContainer,
  749.         theAppleEvent,
  750.         &theDocument,
  751.         &theHTE)
  752.     ) {
  753.         if (theDocument->kind == kDocumentWindow) {
  754.             DoTEPasteSectionRecalc(theDocument);
  755.         } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  756.             SysBeep(1);
  757.             
  758.             return errAEEventNotHandled;
  759.         }
  760.             
  761.         TEFromScrap();
  762.         TEPaste(theHTE);
  763.         EnforceMemory(theDocument, theHTE);
  764.         AdjustScrollbars(theDocument, false);
  765.         DrawPageExtras(theDocument);
  766.             
  767.         theDocument->dirty = true;
  768.     }
  769.  
  770.     return noErr;
  771. } /* DoCopyEdit */
  772.  
  773. /* -----------------------------------------------------------------------
  774.         Name:             DoCutEdit
  775.         Purpose:        Performs a cut text operation on the current text selection
  776.      -----------------------------------------------------------------------**/
  777.  
  778. pascal OSErr DoCutEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  779. {
  780. #pragma unused (reply,refCon)
  781.  
  782.     OSErr    myErr;
  783.     TEHandle theHTE;
  784.     DPtr     theDocument;
  785.  
  786.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent,&theDocument,&theHTE))
  787.         return myErr;
  788.  
  789.     if (theDocument->kind == kDocumentWindow) {
  790.         DoTECutSectionRecalc(theDocument);
  791.         
  792.         theDocument->dirty = true;
  793.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  794.         if (!AllSelected(theHTE)) {
  795.             SysBeep(1);
  796.         
  797.             return DoCopyEdit(theAppleEvent, reply, refCon);
  798.         }
  799.     }
  800.  
  801.     myErr = (OSErr) ZeroScrap();
  802.     TECut(theHTE);
  803.     TEToScrap();
  804.     AdjustScrollbars(theDocument, false);
  805.     DrawPageExtras(theDocument);
  806.  
  807.     return myErr;
  808. } /* DoCutEdit */
  809.  
  810. /* -----------------------------------------------------------------------
  811.         Name:         DoPasteEdit
  812.         Purpose:        Performs a paste text operation on the text selection specified
  813.                         by the appleEvent direct object (if any)
  814.      -----------------------------------------------------------------------**/
  815.  
  816. pascal OSErr DoPasteEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  817. {
  818. #pragma unused (reply,refCon)
  819.  
  820.     OSErr    myErr;
  821.     TEHandle theHTE;
  822.     DPtr     theDocument;
  823.  
  824.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent, &theDocument, &theHTE))
  825.         return myErr;
  826.  
  827.     if (theDocument->kind == kDocumentWindow) {
  828.         DoTEPasteSectionRecalc(theDocument);
  829.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  830.         SysBeep(1);
  831.             
  832.         return errAEEventNotHandled;
  833.     }
  834.     
  835.     TEFromScrap();
  836.     TEPaste(theHTE);
  837.     EnforceMemory(theDocument, theHTE);
  838.     AdjustScrollbars(theDocument, false);
  839.     DrawPageExtras(theDocument);
  840.         
  841.     theDocument->dirty = true;
  842.  
  843.     return noErr;
  844. } /* DoPasteEdit */
  845.  
  846. /* -----------------------------------------------------------------------
  847.         Name:         DoDeleteEdit
  848.         Purpose:        Performs a delete text operation on the selection specified
  849.                         by the appleEvent direct object (if any)
  850.      -----------------------------------------------------------------------**/
  851.  
  852. pascal OSErr DoDeleteEdit(const AppleEvent *theAppleEvent, AppleEvent *reply, long refcon)
  853. {
  854. #pragma unused (reply,refcon)
  855.  
  856.     OSErr     myErr;
  857.     TEHandle theHTE;
  858.     DPtr     theDocument;
  859.  
  860.     if (myErr = SetSelectionOfAppleEventDirectObject(theAppleEvent, &theDocument, &theHTE))
  861.         return myErr;
  862.  
  863.     if (theDocument->kind == kDocumentWindow) {
  864.         DoTEDeleteSectionRecalc(theDocument);
  865.     } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  866.         if (!AllSelected(theHTE)) {
  867.             SysBeep(1);
  868.                 
  869.             return errAEEventNotHandled;
  870.         }
  871.         theDocument->u.cons.fence = 0;
  872.     }
  873.     
  874.     TEDelete(theHTE);
  875.     AdjustScrollbars(theDocument, false);
  876.     DrawPageExtras(theDocument);
  877.     theDocument->dirty = true;
  878.  
  879.     return noErr;
  880. } /*DoDeleteEdit*/
  881.  
  882. #endif
  883.  
  884. void RecalcFontInfo(TEHandle te)
  885. {
  886.     TEPtr        t;
  887.     short        oldFont;
  888.     short        oldSize;
  889.     FontInfo    info;
  890.  
  891.     HLock((Handle) te);
  892.  
  893.     t             = *te;
  894.     oldFont    =    t->inPort->txFont;
  895.     oldSize    =    t->inPort->txSize;
  896.  
  897.     SetPort(t->inPort);
  898.     TextFont(t->txFont);
  899.     TextSize(t->txSize);
  900.     GetFontInfo(&info);
  901.     TextFont(oldFont);
  902.     TextSize(oldSize);
  903.  
  904.     t->lineHeight    =    info.ascent+info.descent+info.leading;
  905.     t->fontAscent    =    info.ascent;
  906.     InvalRect(&t->viewRect);
  907.     HUnlock((Handle) te);
  908.  
  909.     TECalText(te);
  910. }
  911.  
  912. #ifndef RUNTIME
  913.  
  914. /* -----------------------------------------------------------------------
  915.         Name:         SetWindowProperty
  916.         Purpose:        Sets the window property specified in theWindowPropToken to
  917.                         be that supplied in dataDesc.
  918.      -----------------------------------------------------------------------**/
  919.  
  920. pascal OSErr SetWindowProperty(const AEDesc *theWPTokenDesc, const AEDesc *dataDesc)
  921. {
  922.       Str255          name;
  923.     DPtr            theDocument;
  924.     short                 size;
  925.     short                 font;
  926.     OSErr           err;
  927.     OSErr           ignoreErr;
  928.     Rect            thePosnRect;
  929.     Boolean         theBoolean;
  930.     TEHandle        theHTE;
  931.     GrafPtr         oldPort;
  932.     Point           thePosn;
  933.     THPrint         theTHPrint;
  934.     windowPropToken theWindowPropToken;
  935.     AEDesc          newDesc;
  936.     AEDesc          tokenDesc;
  937.     Size            tokenSize;
  938.     TextToken       myTextToken;
  939.     short           hOffset;
  940.     short           vOffset;
  941.  
  942.     if (err = AECoerceDesc(theWPTokenDesc, typeMyWindowProp, &newDesc))
  943.         return err;
  944.  
  945.     GetRawDataFromDescriptor(
  946.         &newDesc,
  947.         (Ptr)&theWindowPropToken,
  948.         sizeof(theWindowPropToken),
  949.         &tokenSize);
  950.  
  951.     err = AEDisposeDesc(&newDesc);
  952.  
  953.     GetPort(&oldPort);
  954.     SetPort(theWindowPropToken.tokenWindowToken);
  955.  
  956.     theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  957.  
  958.     switch (theWindowPropToken.tokenProperty) {
  959.     case pName:
  960.         err = GetPStringFromDescriptor(dataDesc, (char *)name);
  961.         if (err==noErr)
  962.             if (theDocument->kind != kDocumentWindow)
  963.                 return errAEEventNotHandled;
  964.             else if (name[0] == 0)
  965.                 err = errAEWrongDataType;
  966.             else {
  967.                 SetWTitle(theWindowPropToken.tokenWindowToken, name);
  968.                 PLstrcpy(theDocument->theFileName, name); /* Should we do this??? */
  969.                 theDocument->dirty = true;
  970.             }
  971.         break;
  972.  
  973.     case pText:
  974.         theHTE = theDocument->theText;
  975.         TESetSelect(0, 32000, theHTE);
  976.  
  977.         if (theDocument->kind == kDocumentWindow) {
  978.             DoTEDeleteSectionRecalc(theDocument);
  979.         } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  980.             SysBeep(1);
  981.             
  982.             return errAEEventNotHandled;
  983.         }
  984.         
  985.         TEDelete(theHTE);
  986.         GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  987.         EnforceMemory(theDocument, theHTE);
  988.         
  989.         theDocument->dirty = true;
  990.         break;
  991.  
  992.     case pBounds:
  993.         err = GetRectFromDescriptor(dataDesc, &thePosnRect);
  994.         /* the rectangle is for the structure region, and is in global coordinates */
  995.         /* MoveWindow and SizeWindow apply to the content region, so we have to massage a little */
  996.  
  997.         thePosnRect.top    += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.top -
  998.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.top;
  999.  
  1000.         thePosnRect.left   += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.left -
  1001.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.left;
  1002.  
  1003.         thePosnRect.bottom += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.bottom -
  1004.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.bottom;
  1005.  
  1006.         thePosnRect.right  += (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.right -
  1007.                                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.right;
  1008.  
  1009.         if (EmptyRect(&thePosnRect))
  1010.             err = errAECorruptData;
  1011.         else {
  1012.             MoveWindow(
  1013.                 theWindowPropToken.tokenWindowToken,
  1014.                 thePosnRect.left,
  1015.                 thePosnRect.top,
  1016.                 false);
  1017.             SizeWindow(
  1018.                 theWindowPropToken.tokenWindowToken,
  1019.                 thePosnRect.right- thePosnRect.left,
  1020.                 thePosnRect.bottom-thePosnRect.top,
  1021.                 true);
  1022.             ResizeWindow(theDocument);
  1023.         }
  1024.         break;
  1025.  
  1026.     case pPosition:
  1027.         err = GetPointFromDescriptor(dataDesc, &thePosn);
  1028.         /* the point is for the structure region, and is in global coordinates */
  1029.         /* MoveWindow applies to the content region, so we have to massage a little */
  1030.  
  1031.         hOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.left -
  1032.                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.left;
  1033.  
  1034.         vOffset = (**((WindowPeek)theWindowPropToken.tokenWindowToken)->contRgn).rgnBBox.top -
  1035.                      (**((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn).rgnBBox.top;
  1036.  
  1037.         thePosn.v  += vOffset;
  1038.         thePosn.h  += hOffset;
  1039.  
  1040.         MoveWindow(
  1041.             theWindowPropToken.tokenWindowToken,
  1042.             thePosn.h,
  1043.             thePosn.v,
  1044.             false);
  1045.  
  1046.         ResizeWindow(theDocument);
  1047.         break;
  1048.  
  1049.     case pIsZoomed:
  1050.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1051.         if (theBoolean)
  1052.             ZoomWindow(qd.thePort, inZoomOut, false);
  1053.         else
  1054.             ZoomWindow(qd.thePort, inZoomIn, false);
  1055.  
  1056.         ResizeWindow(theDocument);
  1057.         break;
  1058.  
  1059.     case pVisible:
  1060.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1061.         if (theBoolean)
  1062.             DoShowWindow(theWindowPropToken.tokenWindowToken);
  1063.         else
  1064.             DoHideWindow(theWindowPropToken.tokenWindowToken);
  1065.         break;
  1066.  
  1067.     case pPageSetup:
  1068.         err = GetTHPrintFromDescriptor(dataDesc, &theTHPrint);
  1069.  
  1070.         if (theTHPrint) {
  1071.             if (theDocument->thePrintSetup)
  1072.                 DisposHandle((Handle)theDocument->thePrintSetup);
  1073.  
  1074.             theDocument->thePrintSetup = theTHPrint;
  1075.  
  1076.             ResizePageSetupForDocument(theDocument);
  1077.         }
  1078.         break;
  1079.  
  1080.     case pShowBorders:
  1081.         if (theDocument->kind != kDocumentWindow)
  1082.             return errAEEventNotHandled;
  1083.             
  1084.         err = GetBooleanFromDescriptor(dataDesc, &theBoolean);
  1085.         theDocument->u.reg.showBorders = theBoolean;
  1086.         if (theBoolean)
  1087.             DrawPageExtras(theDocument); /* Does the clipping as well as drawing borders/page breaks */
  1088.         else
  1089.             InvalidateDocument(theDocument);
  1090.         break;
  1091.  
  1092.     case pFont:
  1093.         err = GetPStringFromDescriptor(dataDesc, (char *)name);
  1094.         GetFNum(name, &font);
  1095.     
  1096.         (*theDocument->theText)->txFont = font;
  1097.         RecalcFontInfo(theDocument->theText);
  1098.         AdjustScrollbars(theDocument, false);
  1099.         DrawPageExtras(theDocument);
  1100.         
  1101.         if (theDocument->kind == kDocumentWindow)
  1102.             theDocument->dirty = true;
  1103.         break;
  1104.  
  1105.     case pPointSize:
  1106.         err = GetIntegerFromDescriptor(dataDesc, &size);
  1107.  
  1108.         (*theDocument->theText)->txSize = size;
  1109.         RecalcFontInfo(theDocument->theText);
  1110.         AdjustScrollbars(theDocument, false);
  1111.         DrawPageExtras(theDocument);
  1112.         
  1113.         if (theDocument->kind == kDocumentWindow)
  1114.             theDocument->dirty = true;
  1115.         break;
  1116.  
  1117.     case pSelection:
  1118.         err = AECoerceDesc(dataDesc, typeMyText, &tokenDesc);
  1119.  
  1120.         GetRawDataFromDescriptor(&tokenDesc,
  1121.                                                          (Ptr)&myTextToken,
  1122.                                                          sizeof(myTextToken),
  1123.                                                          &tokenSize);
  1124.  
  1125.         ignoreErr = AEDisposeDesc(&tokenDesc);
  1126.  
  1127.         if (err == noErr) {
  1128.             /* got a text token */
  1129.  
  1130.             theDocument = DPtrFromWindowPtr(myTextToken.tokenWindow);
  1131.             theHTE      = theDocument->theText;
  1132.  
  1133.             TESetSelect(
  1134.                 myTextToken.tokenOffset-1,
  1135.                 myTextToken.tokenOffset+myTextToken.tokenLength-1,
  1136.                 theHTE);
  1137.         }
  1138.         break;
  1139.  
  1140.     case pIndex:
  1141.     case pIsModal:
  1142.     case pIsResizable:
  1143.     case pHasTitleBar:
  1144.     case pHasCloseBox:
  1145.     case pIsFloating:
  1146.     case pIsZoomable:
  1147.     case pIsModified:
  1148.         err = errAEEventNotHandled; /* We don't allow these to be set */
  1149.         break;
  1150.     }
  1151.     
  1152.     SetPort(oldPort);
  1153.  
  1154.     return err;
  1155. } /* SetWindowProperty */
  1156.  
  1157. /* -----------------------------------------------------------------------
  1158.         Name:         SetTextProperty
  1159.         Purpose:        Sets the text property specfied by theTextPropToken to
  1160.                         that in dataDesc.
  1161.      -----------------------------------------------------------------------**/
  1162.  
  1163. pascal OSErr SetTextProperty(const AEDesc *tokenDesc, const AEDesc *dataDesc)
  1164. {
  1165.     TEHandle      theHTE;
  1166.     DPtr          theDoc;
  1167.     OSErr         myErr;
  1168.     textPropToken theTextPropToken;
  1169.     AEDesc        newDesc;
  1170.     Size          tokenSize;
  1171.  
  1172.     newDesc.dataHandle = nil;
  1173.  
  1174.     if (myErr = AECoerceDesc(tokenDesc, typeMyTextProp, &newDesc))
  1175.         return myErr;
  1176.  
  1177.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken, sizeof(theTextPropToken), &tokenSize);
  1178.     myErr             =    AEDisposeDesc(&newDesc);
  1179.     theDoc             =    DPtrFromWindowPtr(theTextPropToken.propertyTextToken.tokenWindow);
  1180.     
  1181.     if (theDoc->kind == kDocumentWindow)
  1182.         theDoc->dirty     =    true;
  1183.  
  1184.     if (theTextPropToken.propertyProperty == pText) {
  1185.         theHTE = theDoc->theText;
  1186.         TESetSelect(
  1187.             theTextPropToken.propertyTextToken.tokenOffset-1,
  1188.             theTextPropToken.propertyTextToken.tokenOffset+theTextPropToken.propertyTextToken.tokenLength-1,
  1189.             theHTE);
  1190.         
  1191.         if (theDoc->kind == kDocumentWindow) {
  1192.             DoTEDeleteSectionRecalc(theDoc);
  1193.         } else if (!theDoc->u.cons.selected || (*theHTE)->selStart < theDoc->u.cons.fence) {
  1194.             SysBeep(1);
  1195.             
  1196.             return errAEEventNotHandled;
  1197.         }
  1198.         
  1199.         TEDelete(theHTE);
  1200.         myErr = GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  1201.         EnforceMemory(theDoc, theHTE);
  1202.             
  1203.         theDoc->dirty = true;
  1204.         
  1205.         return myErr;
  1206.     }
  1207.  
  1208.     return errAEWrongDataType;
  1209. } /* SetTextProperty */
  1210.  
  1211. /* -----------------------------------------------------------------------
  1212.         Name:         HandleSetData
  1213.         Purpose:        Resolves the object into a token (could be one of many) and
  1214.                         the sets the data of that object to dataDesc.
  1215.      -----------------------------------------------------------------------**/
  1216.  
  1217. pascal OSErr HandleSetData(const AEDesc *theObj, const AEDesc *dataDesc)
  1218. {
  1219.     OSErr           myErr;
  1220.     AEDesc          newDesc;
  1221.     DPtr            theDocument;
  1222.     TEHandle        theHTE;
  1223.     TextToken       theTextToken;
  1224.     Size            tokenSize;
  1225.     AEDesc          objTokenDesc;
  1226.     OSErr           ignoreErr;
  1227.  
  1228.     objTokenDesc.dataHandle = nil;
  1229.     newDesc.dataHandle      = nil;
  1230.  
  1231.     /*
  1232.         Coerce theObj into a token which we can use -
  1233.              set the property or data for that token
  1234.     */
  1235.  
  1236.     myErr = AEResolve(theObj ,kAEIDoMinimum, &objTokenDesc);
  1237.  
  1238.     /* We don't actually allow ANY app property setting, but
  1239.         just incase we'll decode looking for an typeMyApplProp and flag an error -
  1240.          do same for menu related tokens
  1241.     */
  1242.  
  1243.     if (
  1244.         (objTokenDesc.descriptorType == typeMyApplProp) ||
  1245.         (objTokenDesc.descriptorType == typeMyMenu    ) ||
  1246.         (objTokenDesc.descriptorType == typeMyMenuProp) ||
  1247.         (objTokenDesc.descriptorType == typeMyMenuItem) ||
  1248.         (objTokenDesc.descriptorType == typeMyItemProp)
  1249.     )
  1250.         myErr = errAEWrongDataType;
  1251.     else if (objTokenDesc.descriptorType == typeMyWindowProp)
  1252.         myErr = SetWindowProperty(&objTokenDesc, dataDesc);
  1253.     else if (objTokenDesc.descriptorType == typeMyTextProp)
  1254.         myErr = SetTextProperty(&objTokenDesc, dataDesc);
  1255.     else if (objTokenDesc.descriptorType == typeMyText)
  1256.         if (!AECoerceDesc(&objTokenDesc, typeMyText, &newDesc)) {
  1257.             GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextToken, sizeof(theTextToken), &tokenSize);
  1258.  
  1259.             myErr         = AEDisposeDesc(&newDesc);
  1260.             theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  1261.             theHTE        = theDocument->theText;
  1262.  
  1263.             TESetSelect(
  1264.                 theTextToken.tokenOffset-1,
  1265.                 theTextToken.tokenOffset+theTextToken.tokenLength-1,
  1266.                 theHTE);
  1267.                 
  1268.             if (theDocument->kind == kDocumentWindow) {
  1269.                 DoTEDeleteSectionRecalc(theDocument);
  1270.             } else if (!theDocument->u.cons.selected || (*theHTE)->selStart < theDocument->u.cons.fence) {
  1271.                 SysBeep(1);
  1272.                 
  1273.                 return errAEEventNotHandled;
  1274.             }
  1275.             
  1276.             TEDelete(theHTE);
  1277.             myErr = GetTextFromDescIntoTEHandle(dataDesc, theHTE);
  1278.             EnforceMemory(theDocument, theHTE);
  1279.                 
  1280.             theDocument->dirty = true;
  1281.         }
  1282.  
  1283.     ignoreErr = AEDisposeDesc(&objTokenDesc);
  1284.  
  1285.     return myErr;
  1286. }    /* HandleSetData */
  1287.  
  1288. /*
  1289.     A few convenient FORWARDS...
  1290. */
  1291.  
  1292. pascal OSErr MakeWindowObj(WindowPtr theWindow, AEDesc *dMyDoc);
  1293.  
  1294. /*
  1295.     Back to real code
  1296. */
  1297. pascal OSErr MakeSelTextObj(WindowPtr theWindow, TEHandle theTextEditHandle, AEDesc *selTextObj)
  1298. /*
  1299.     This is a hack to get the AppleScript Alpha to work...
  1300. */
  1301. {
  1302.     OSErr    myErr;
  1303.     OSErr    ignoreErr;
  1304.     AEDesc   dNull;
  1305.     AEDesc   dMyDoc;
  1306.     AEDesc   startOfs;
  1307.     AEDesc   endOfs;
  1308.     AEDesc   startObj;
  1309.     AEDesc   endObj;
  1310.     AEDesc   rangeDesc;
  1311.     long     startChar;
  1312.     long     endChar;
  1313.     Boolean  spotFlag;
  1314.  
  1315.     myErr = noErr;
  1316.  
  1317.     if (theWindow==nil)
  1318.         return noErr;
  1319.  
  1320.     selTextObj->dataHandle = nil;
  1321.     dMyDoc.dataHandle      = nil;
  1322.     startObj.dataHandle    = nil;
  1323.     endObj.dataHandle      = nil;
  1324.  
  1325.     /*
  1326.         make the window object
  1327.     */
  1328.  
  1329.     if (myErr = MakeWindowObj(theWindow, &dMyDoc))
  1330.         return myErr;
  1331.  
  1332.     /* get the start and end of selection */
  1333.  
  1334.     startChar = (*theTextEditHandle)->selStart+1;    /* start counting obj's from 1, not 0 */
  1335.     endChar   = (*theTextEditHandle)->selEnd;
  1336.     spotFlag  = ((*theTextEditHandle)->selStart == (*theTextEditHandle)->selEnd);
  1337.  
  1338.     if (myErr = CreateOffsetDescriptor(startChar, &startOfs))
  1339.         return myErr;
  1340.  
  1341.     if (spotFlag)
  1342.         myErr = CreateObjSpecifier(cSpot, &dMyDoc, formAbsolutePosition, &startOfs, true, selTextObj);
  1343.     else {
  1344.         /* not a spot - must represent as range */
  1345.         /* make obj for start char */
  1346.  
  1347.         myErr = AECreateDesc(typeNull, nil , 0, &dNull);
  1348.  
  1349.         myErr = CreateObjSpecifier(cChar, &dNull, formAbsolutePosition, &startOfs, false, &startObj);
  1350.  
  1351.         if (myErr==noErr)
  1352.             myErr = CreateOffsetDescriptor(endChar, &endOfs);
  1353.  
  1354.         if (myErr==noErr)
  1355.             myErr = CreateObjSpecifier(cChar, &dNull, formAbsolutePosition, &endOfs, false, &endObj);
  1356.  
  1357.         if (myErr==noErr)
  1358.             myErr = CreateRangeDescriptor(&startObj, &endObj, false, &rangeDesc);
  1359.  
  1360.         if (myErr==noErr)
  1361.             myErr = CreateObjSpecifier(cChar, &dMyDoc, formRange, &rangeDesc, true, selTextObj);
  1362.  
  1363.         if (startObj.dataHandle)
  1364.           ignoreErr = AEDisposeDesc(&startObj);
  1365.  
  1366.         if (startOfs.dataHandle)
  1367.           ignoreErr = AEDisposeDesc(&startOfs);
  1368.  
  1369.         if (endObj.dataHandle)
  1370.           ignoreErr = AEDisposeDesc(&endObj);
  1371.  
  1372.         if (endOfs.dataHandle)
  1373.           ignoreErr = AEDisposeDesc(&endOfs);
  1374.     }
  1375.  
  1376.     return myErr;
  1377. }    /* MakeSelTextObj */
  1378.  
  1379. /* -----------------------------------------------------------------------
  1380.         Name:             DoSetData
  1381.         Purpose:        Handles the SetData Apple Event, extracting the direct
  1382.                                 object (which says what to set) and the data (what to set
  1383.                                 it to).
  1384.      -----------------------------------------------------------------------**/
  1385.  
  1386. pascal OSErr DoSetData(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon)
  1387. {
  1388. #pragma unused (reply, handlerRefCon)
  1389.  
  1390.     OSErr  myErr;
  1391.     OSErr  ignoreErr;
  1392.     AEDesc myDirObj;
  1393.     AEDesc myDataDesc;
  1394.  
  1395.     myDataDesc.dataHandle = nil;
  1396.     myDirObj.dataHandle   = nil;
  1397.  
  1398.     /* pick up the direct object, which is the object whose data is to be set */
  1399.  
  1400.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  1401.  
  1402.     /* now the data to set it to - typeWildCard means get as is*/
  1403.     if (myErr == noErr)
  1404.         myErr = AEGetParamDesc(theAppleEvent, keyAEData, typeWildCard, &myDataDesc);
  1405.  
  1406.     /* missing any parameters? */
  1407.     if (myErr == noErr)
  1408.         myErr = GotRequiredParams(theAppleEvent);
  1409.  
  1410.     /* set the data */
  1411.     if (myErr == noErr)
  1412.         myErr = HandleSetData(&myDirObj, &myDataDesc);
  1413.  
  1414.     if (myDataDesc.dataHandle)
  1415.         ignoreErr = AEDisposeDesc(&myDataDesc);
  1416.  
  1417.     if (myDirObj.dataHandle)
  1418.         ignoreErr = AEDisposeDesc(&myDirObj);
  1419.  
  1420.     return myErr;
  1421. }    /* DoSetData */
  1422.  
  1423. pascal OSErr BuildStyledTextDesc(TEHandle theHTE, short start, short howLong, AEDesc *resultDesc)
  1424. {
  1425.     AEDesc       listDesc;
  1426.     OSErr        myErr;
  1427.     OSErr        ignoreErr;
  1428.  
  1429.     listDesc.dataHandle = nil;
  1430.  
  1431.     TESetSelect(start-1, start+howLong-2, theHTE);
  1432.  
  1433.     myErr = AECreateList(nil, 0, true,  &listDesc);
  1434.  
  1435.     HLock((Handle)(**theHTE).hText);
  1436.  
  1437.     if (myErr==noErr)
  1438.         myErr = AEPutKeyPtr(&listDesc,
  1439.                                   keyAEText,
  1440.                                                 typeChar,
  1441.                                                 (Ptr)&(*(**theHTE).hText)[start-1],
  1442.                                                 howLong);
  1443.  
  1444.     HUnlock((Handle)(**theHTE).hText);
  1445.  
  1446.     myErr = AEPutKeyPtr(&listDesc, keyAEStyles, typeScrapStyles, (Ptr)nil, 0);
  1447.  
  1448.     if (myErr==noErr)
  1449.         myErr = AECoerceDesc(&listDesc, typeStyledText, resultDesc); // should be typeIntlText
  1450.  
  1451.     if (listDesc.dataHandle)
  1452.         ignoreErr = AEDisposeDesc(&listDesc);
  1453.  
  1454.     return myErr;
  1455. }
  1456.  
  1457. /* -----------------------------------------------------------------------
  1458.         Name:             GetTextProperty
  1459.         Purpose:        Fills dataDesc with the requested text property.
  1460.      -----------------------------------------------------------------------**/
  1461.  
  1462. pascal OSErr GetTextProperty(const AEDesc *theTokenDesc, AEDesc *dataDesc)
  1463. {
  1464.       DPtr          theDocument;
  1465.     TEHandle      theHTE;
  1466.     short         theSize;
  1467.     GrafPtr       oldPort;
  1468.     textPropToken theTextPropToken;
  1469.     OSErr         myErr;
  1470.     Size          tokenSize;
  1471.     AEDesc        newDesc;
  1472.  
  1473.       if (myErr = AECoerceDesc(theTokenDesc, typeMyTextProp, &newDesc))
  1474.         return myErr;
  1475.  
  1476.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theTextPropToken, sizeof(theTextPropToken), &tokenSize);
  1477.     myErr= AEDisposeDesc(&newDesc);
  1478.  
  1479.     /*
  1480.         For each property we build a descriptor to be returned as the reply.
  1481.     */
  1482.  
  1483.     theDocument = DPtrFromWindowPtr(theTextPropToken.propertyTextToken.tokenWindow);
  1484.     theHTE         = theDocument->theText;
  1485.  
  1486.     if (theTextPropToken.propertyProperty == pText)
  1487.         myErr =
  1488.             BuildStyledTextDesc(
  1489.                 theHTE,
  1490.                 theTextPropToken.propertyTextToken.tokenOffset,
  1491.                 theTextPropToken.propertyTextToken.tokenLength,
  1492.                 dataDesc);
  1493.     else if (theTextPropToken.propertyProperty == pStringWidth)  {
  1494.         GetPort(&oldPort);
  1495.         SetPort(theTextPropToken.propertyTextToken.tokenWindow);
  1496.  
  1497.         HLock((Handle)(*theHTE)->hText);
  1498.         theSize =
  1499.             TextWidth(
  1500.                 &(*theHTE)->hText,
  1501.                 theTextPropToken.propertyTextToken.tokenOffset-1,
  1502.                 theTextPropToken.propertyTextToken.tokenLength);
  1503.         HUnlock((Handle)(*theHTE)->hText);
  1504.  
  1505.         SetPort(oldPort);
  1506.         return CreateOffsetDescriptor(theSize, dataDesc);
  1507.     }  else
  1508.         myErr = errAEEventNotHandled;
  1509.  
  1510.     return myErr;
  1511. } /*GetTextProperty*/
  1512.  
  1513. /* -----------------------------------------------------------------------
  1514.         Name:             GetWindowProperty
  1515.         Purpose:        Fills dataDesc with the requested window property.
  1516.      -----------------------------------------------------------------------**/
  1517. typedef Rect **RectHandle;
  1518.  
  1519. pascal OSErr GetWindowProperty(const AEDesc *theWPTokenObj, AEDesc *dataDesc)
  1520. {
  1521.      OSErr           theErr;
  1522.     Str255          theName;
  1523.     Boolean         theBoolean;
  1524.     Rect            theRect;
  1525.     Point           thePoint;
  1526.     Rect            winRect;
  1527.     Rect            userRect;
  1528.     short           theIndex;
  1529.     DPtr            theDocument;
  1530.     TEHandle        theHTE;
  1531.     windowPropToken theWindowPropToken;
  1532.     AEDesc          newDesc;
  1533.     Size            tokenSize;
  1534.  
  1535.       if (theErr = AECoerceDesc(theWPTokenObj,typeMyWindowProp, &newDesc))
  1536.           return theErr;
  1537.  
  1538.     GetRawDataFromDescriptor(
  1539.         &newDesc,
  1540.         (Ptr)&theWindowPropToken,
  1541.         sizeof(theWindowPropToken),
  1542.         &tokenSize);
  1543.  
  1544.     theErr = AEDisposeDesc(&newDesc);
  1545.  
  1546.     theErr = kAEGenericErr;
  1547.  
  1548.     if (theWindowPropToken.tokenProperty == pName)  {
  1549.         GetWTitle(theWindowPropToken.tokenWindowToken, theName);
  1550.         theErr = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1551.     }
  1552.  
  1553.     if (theWindowPropToken.tokenProperty == pText) {
  1554.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1555.         theHTE      = theDocument->theText;
  1556.  
  1557.         theErr = BuildStyledTextDesc(theHTE, 1, (**theHTE).teLength, dataDesc);
  1558.     }
  1559.  
  1560.     if (theWindowPropToken.tokenProperty == pBounds) {
  1561.         SetPort(theWindowPropToken.tokenWindowToken);
  1562.  
  1563.         theRect = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox;
  1564.  
  1565.         theErr  = AECreateDesc(typeQDRectangle, (Ptr)&theRect, sizeof(theRect), dataDesc);
  1566.     }
  1567.  
  1568.     if (theWindowPropToken.tokenProperty == pPosition) {
  1569.         thePoint.v = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox.top;
  1570.         thePoint.h = (*((WindowPeek)theWindowPropToken.tokenWindowToken)->strucRgn)->rgnBBox.left;
  1571.  
  1572.         theErr   = AECreateDesc(typeQDPoint, (Ptr)&thePoint, sizeof(thePoint), dataDesc);
  1573.     }
  1574.  
  1575.     if (theWindowPropToken.tokenProperty == pVisible) {
  1576.         theBoolean = ((WindowPeek)theWindowPropToken.tokenWindowToken)->visible;
  1577.  
  1578.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1579.     }
  1580.  
  1581.     if (theWindowPropToken.tokenProperty == pIsModal) {
  1582.         theBoolean = false;
  1583.  
  1584.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1585.     }
  1586.  
  1587.     if (theWindowPropToken.tokenProperty == pShowBorders) {
  1588.         theDocument  = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1589.         theBoolean   = (theDocument->kind == kDocumentWindow) ? theDocument->u.reg.showBorders : false;
  1590.  
  1591.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1592.     }
  1593.  
  1594.     if (theWindowPropToken.tokenProperty == pIsZoomed)  {
  1595.         if (((WindowPeek)theWindowPropToken.tokenWindowToken)->spareFlag) {
  1596.             SetPort(theWindowPropToken.tokenWindowToken);
  1597.  
  1598.             userRect = **((RectHandle)((WindowPeek)qd.thePort)->dataHandle);
  1599.             winRect  = qd.thePort->portRect;
  1600.             LocalToGlobal((Point *)&winRect.top);
  1601.             LocalToGlobal((Point *)&winRect.bottom);
  1602.  
  1603.             theBoolean = !EqualRect(&userRect, &winRect);
  1604.         } else
  1605.             theBoolean = false;
  1606.  
  1607.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1608.     }
  1609.  
  1610.     if ((theWindowPropToken.tokenProperty == pIsResizable) ||
  1611.          (theWindowPropToken.tokenProperty == pHasTitleBar) ||
  1612.          (theWindowPropToken.tokenProperty == pIsZoomable)
  1613.     ) {
  1614.         theBoolean = theDocument->kind != kWorksheetWindow;
  1615.  
  1616.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1617.     }
  1618.  
  1619.     if (theWindowPropToken.tokenProperty == pHasCloseBox) {
  1620.         theBoolean = true;
  1621.  
  1622.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1623.     }
  1624.  
  1625.     if (theWindowPropToken.tokenProperty == pIsFloating) {
  1626.         theBoolean = false;
  1627.  
  1628.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1629.     }
  1630.  
  1631.     if (theWindowPropToken.tokenProperty == pIsModified) {
  1632.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1633.  
  1634.         theBoolean  = (theDocument->kind == kDocumentWindow) ? theDocument->dirty : true;
  1635.  
  1636.         theErr  = AECreateDesc(typeBoolean, (Ptr)&theBoolean, sizeof(theBoolean), dataDesc);
  1637.     }
  1638.  
  1639.     if (theWindowPropToken.tokenProperty == pIndex) {
  1640.         theIndex = 0;
  1641.         if (theWindowPropToken.tokenWindowToken)
  1642.             do
  1643.                 theIndex++;
  1644.             while (theWindowPropToken.tokenWindowToken != GetWindowPtrOfNthWindow(theIndex));
  1645.  
  1646.         theErr  = AECreateDesc(typeShortInteger, (Ptr)theIndex, sizeof(theIndex), dataDesc);
  1647.     }
  1648.  
  1649.     if (theWindowPropToken.tokenProperty == pPageSetup) {
  1650.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1651.  
  1652.         HLock((Handle)theDocument->thePrintSetup);
  1653.  
  1654.         theErr  = AECreateDesc(typeTPrint, (Ptr)*(theDocument->thePrintSetup), sizeof(TPrint), dataDesc);
  1655.  
  1656.         HUnlock((Handle)theDocument->thePrintSetup);
  1657.     }
  1658.  
  1659.     if (theWindowPropToken.tokenProperty == pSelection) {
  1660.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1661.  
  1662.         theErr  = MakeSelTextObj(theWindowPropToken.tokenWindowToken, theDocument->theText, dataDesc);
  1663.     }
  1664.     
  1665.     if (theWindowPropToken.tokenProperty == pFont) {
  1666.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1667.         
  1668.         GetFontName((*theDocument->theText)->txFont, theName);
  1669.  
  1670.         theErr = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1671.     } 
  1672.     
  1673.     if (theWindowPropToken.tokenProperty == pPointSize) {
  1674.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1675.         theErr =CreateOffsetDescriptor((*theDocument->theText)->txSize, dataDesc);
  1676.     }
  1677.         
  1678.     if (theWindowPropToken.tokenProperty == pScriptTag) {
  1679.         theDocument = DPtrFromWindowPtr(theWindowPropToken.tokenWindowToken);
  1680.         theErr = CreateOffsetDescriptor(FontToScript((*theDocument->theText)->txFont), dataDesc);
  1681.     }
  1682.  
  1683.     return theErr;
  1684. } /* GetWindowProperty */
  1685.  
  1686. /** -----------------------------------------------------------------------
  1687.         Name:             GetApplicationProperty
  1688.         Purpose:        Fills dataDesc with the requested application property.
  1689.      -----------------------------------------------------------------------**/
  1690.  
  1691. pascal OSErr GetApplicationProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1692. {
  1693.       OSErr         theErr;
  1694.     Str255        theName;
  1695.     Boolean       isFront;
  1696.     applPropToken theApplPropToken;
  1697.     AEDesc        newDesc;
  1698.     Size          tokenSize;
  1699.  
  1700.     if (theErr = AECoerceDesc(theObjToken, typeMyApplProp, &newDesc))
  1701.         return theErr;
  1702.  
  1703.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theApplPropToken, sizeof(theApplPropToken), &tokenSize);
  1704.  
  1705.     theErr = AEDisposeDesc(&newDesc);
  1706.     theErr = kAEGenericErr;
  1707.  
  1708.     if (theApplPropToken.tokenApplProperty == pName) {
  1709.         PLstrcpy((StringPtr)theName, "\pMacPerl");
  1710.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1711.     }
  1712.  
  1713.     if (theApplPropToken.tokenApplProperty == pVersion)  {
  1714.         PLstrcpy((StringPtr)theName, "\p4.1.0");
  1715.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1716.     }
  1717.  
  1718.     if (theApplPropToken.tokenApplProperty == pIsFrontProcess) {
  1719.         isFront = !gInBackground;
  1720.         theErr  = AECreateDesc(typeBoolean, (Ptr)&isFront, sizeof(isFront), dataDesc);
  1721.     }
  1722.  
  1723.     return theErr;
  1724. } /* GetApplicationProperty */
  1725.  
  1726. /** -----------------------------------------------------------------------
  1727.         Name:             GetMenuProperty
  1728.         Purpose:        Fills dataDesc with the requested menu property.
  1729.      -----------------------------------------------------------------------**/
  1730.  
  1731. pascal OSErr GetMenuProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1732. {
  1733.       OSErr         theErr;
  1734.     Str255        theName;
  1735.     MenuPropToken theMenuPropToken;
  1736.     AEDesc        newDesc;
  1737.     Size          tokenSize;
  1738.  
  1739.     if (theErr = AECoerceDesc(theObjToken, typeMyMenuProp, &newDesc))
  1740.         return theErr;
  1741.  
  1742.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theMenuPropToken, sizeof(theMenuPropToken), &tokenSize);
  1743.  
  1744.     theErr = AEDisposeDesc(&newDesc);
  1745.     theErr = kAEGenericErr;
  1746.  
  1747.     if (theMenuPropToken.theMenuProp == pName)  {
  1748.           PLstrcpy(theName, (**theMenuPropToken.theMenuToken.theTokenMenu).menuData);
  1749.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1750.     }
  1751.  
  1752.     if (theMenuPropToken.theMenuProp == pMenuID) {
  1753.         theErr  =
  1754.             AECreateDesc(
  1755.                 typeShortInteger,
  1756.                 (Ptr)&theMenuPropToken.theMenuToken.theTokenID,
  1757.                 sizeof(theMenuPropToken.theMenuToken.theTokenID),
  1758.                 dataDesc);
  1759.     }
  1760.  
  1761.     return theErr;
  1762. } /* GetMenuProperty */
  1763.  
  1764. /** -----------------------------------------------------------------------
  1765.         Name:         GetMenuItemProperty
  1766.         Purpose:        Fills dataDesc with the requested menu property.
  1767.      -----------------------------------------------------------------------**/
  1768.  
  1769. pascal OSErr GetMenuItemProperty(const AEDesc *theObjToken, AEDesc *dataDesc)
  1770. {
  1771.       OSErr             theErr;
  1772.     Str255            theName;
  1773.     MenuItemPropToken theMenuItemPropToken;
  1774.     AEDesc            newDesc;
  1775.     Size              tokenSize;
  1776.  
  1777.     if (theErr = AECoerceDesc(theObjToken, typeMyItemProp, &newDesc))
  1778.         return theErr;
  1779.  
  1780.     GetRawDataFromDescriptor(&newDesc, (Ptr)&theMenuItemPropToken, sizeof(theMenuItemPropToken), &tokenSize);
  1781.  
  1782.     theErr = AEDisposeDesc(&newDesc);
  1783.     theErr = kAEGenericErr;
  1784.  
  1785.     if (theMenuItemPropToken.theItemProp == pName) {
  1786.           GetItem(
  1787.             theMenuItemPropToken.theItemToken.theMenuToken.theTokenMenu,
  1788.             theMenuItemPropToken.theItemToken.theTokenItem,
  1789.             theName);
  1790.         theErr  = AECreateDesc(typeChar, (Ptr)&theName[1], theName[0], dataDesc);
  1791.     }
  1792.  
  1793.     if (theMenuItemPropToken.theItemProp == pItemNumber) {
  1794.         theErr  =
  1795.             AECreateDesc(
  1796.                 typeShortInteger,
  1797.                 (Ptr)&theMenuItemPropToken.theItemToken.theTokenItem,
  1798.                 sizeof(theMenuItemPropToken.theItemToken.theTokenItem),
  1799.                 dataDesc);
  1800.     }
  1801.  
  1802.     return theErr;
  1803. } /* GetMenuItemProperty */
  1804.  
  1805. /** -----------------------------------------------------------------------
  1806.         Name:         HandleGetData
  1807.         Purpose:        Coerces theObj into a token which we understand and
  1808.                         extracts the data requested in the token and puts it
  1809.                         into dataDesc.
  1810.      -----------------------------------------------------------------------**/
  1811.  
  1812. typedef char chars[32001];
  1813. typedef chars **charsHandle;
  1814.  
  1815. pascal OSErr HandleGetData(AEDesc *theObj, DescType whatType, AEDesc *dataDesc)
  1816. {
  1817. #pragma unused (whatType)
  1818.  
  1819.       OSErr           myErr;
  1820.     AEDesc          newDesc;
  1821.     TextToken       theTextToken;
  1822.     Size            tokenSize;
  1823.     DPtr            theDoc;
  1824.     AEDesc          objTokenDesc;
  1825.  
  1826.     myErr = errAEWrongDataType;
  1827.  
  1828.     /*
  1829.         Coerce theObj into a token which we can use -
  1830.              set the property for that token
  1831.     */
  1832.  
  1833.  
  1834.     if (myErr = AEResolve(theObj, kAEIDoMinimum, &objTokenDesc))
  1835.         return myErr;
  1836.  
  1837.     if (objTokenDesc.descriptorType == typeMyApplProp)
  1838.         myErr = GetApplicationProperty(&objTokenDesc, dataDesc);
  1839.     else if (objTokenDesc.descriptorType == typeMyMenuProp)
  1840.         myErr = GetMenuProperty(&objTokenDesc, dataDesc);
  1841.     else if (objTokenDesc.descriptorType == typeMyItemProp)
  1842.         myErr = GetMenuItemProperty(&objTokenDesc, dataDesc);
  1843.     else if (objTokenDesc.descriptorType == typeMyTextProp)
  1844.         myErr = GetTextProperty(&objTokenDesc, dataDesc);
  1845.     else if (objTokenDesc.descriptorType == typeMyWindowProp)
  1846.         myErr = GetWindowProperty(&objTokenDesc, dataDesc);
  1847.     else if (objTokenDesc.descriptorType == typeMyText)
  1848.         if (!AECoerceDesc(&objTokenDesc, typeMyText, &newDesc)) {
  1849.             GetRawDataFromDescriptor(
  1850.                 &newDesc,
  1851.                 (Ptr)&theTextToken,
  1852.                 sizeof(theTextToken),
  1853.                 &tokenSize);
  1854.  
  1855.             myErr     = AEDisposeDesc(&newDesc);
  1856.  
  1857.             theDoc    = DPtrFromWindowPtr(theTextToken.tokenWindow);
  1858.  
  1859.             myErr     =
  1860.                 BuildStyledTextDesc(
  1861.                     theDoc->theText,
  1862.                     theTextToken.tokenOffset,
  1863.                     theTextToken.tokenLength,
  1864.                     dataDesc);
  1865.         }
  1866.  
  1867.     return myErr;
  1868. }    /* HandleGetData */
  1869.  
  1870. /** -----------------------------------------------------------------------
  1871.         Name:         DoGetData
  1872.         Purpose:        Handles the GetData AppleEvent.
  1873.      -----------------------------------------------------------------------**/
  1874.  
  1875. pascal OSErr DoGetData(
  1876.     const AppleEvent *theAppleEvent,
  1877.     AppleEvent *reply,
  1878.     long handlerRefCon)
  1879. {
  1880. #pragma unused (handlerRefCon)
  1881.  
  1882.     OSErr    myErr;
  1883.     OSErr    tempErr;
  1884.     AEDesc   myDirObj;
  1885.     AEDesc   myDataDesc;
  1886.     Size     actualSize;
  1887.     DescType returnedType;
  1888.     DescType reqType;
  1889.  
  1890.     myDataDesc.dataHandle = nil;
  1891.     myDirObj.dataHandle   = nil;
  1892.  
  1893.     /*
  1894.         extract the direct object, which is the object whose data is to be returned
  1895.     */
  1896.  
  1897.     myErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  1898.  
  1899.     /*
  1900.         now the get the type of data wanted - optional
  1901.     */
  1902.  
  1903.     tempErr =
  1904.         AEGetParamPtr(
  1905.             theAppleEvent,
  1906.             keyAERequestedType,
  1907.             typeType,
  1908.             &returnedType,
  1909.             (Ptr)&reqType,
  1910.             sizeof(reqType),
  1911.             &actualSize);
  1912.  
  1913.     if (tempErr!=noErr)
  1914.         reqType = typeChar;
  1915.  
  1916.     if (myErr == noErr)
  1917.         myErr = GotRequiredParams(theAppleEvent);
  1918.  
  1919.     /* get the data */
  1920.     if (myErr == noErr)
  1921.         myErr = HandleGetData(&myDirObj, reqType, &myDataDesc);
  1922.  
  1923.     /* if they wanted a reply, attach it now */
  1924.     if (myErr==noErr)
  1925.         if (reply->descriptorType != typeNull)
  1926.             myErr = AEPutParamDesc(reply, keyDirectObject, &myDataDesc);
  1927.  
  1928.      if (myDataDesc.dataHandle)
  1929.           tempErr = AEDisposeDesc(&myDataDesc);
  1930.  
  1931.      if (myDirObj.dataHandle)
  1932.           tempErr = AEDisposeDesc(&myDirObj);
  1933.  
  1934.     return myErr;
  1935. }    /* DoGetData */
  1936.  
  1937.  
  1938. /** -----------------------------------------------------------------------
  1939.         Name:         DoGetDataSize
  1940.         Purpose:        Handles the GetDataSize AppleEvent.
  1941.      -----------------------------------------------------------------------**/
  1942.  
  1943. pascal OSErr DoGetDataSize(
  1944.     const AppleEvent *theAppleEvent,
  1945.     AppleEvent *reply,
  1946.     long       handlerRefCon)
  1947. {
  1948. #pragma unused (handlerRefCon)
  1949.  
  1950.     OSErr     myErr;
  1951.     OSErr     tempErr;
  1952.     AEDesc    myDirObj;
  1953.     AEDesc    myDataDesc;
  1954.     Size      actualSize;
  1955.     DescType  returnedType;
  1956.     DescType  reqType;
  1957.     long      dataSize;
  1958.  
  1959.     myDataDesc.dataHandle = nil;
  1960.     myDirObj.dataHandle = nil;
  1961.  
  1962.     /* pick up the direct object, which is the object whose data is to be sized */
  1963.  
  1964.     myErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  1965.  
  1966.     /* now the get the type wanted - optional*/
  1967.  
  1968.     tempErr =
  1969.         AEGetParamPtr(
  1970.             theAppleEvent,
  1971.             keyAERequestedType,
  1972.             typeType,
  1973.             &returnedType,
  1974.             (Ptr)&reqType,
  1975.             sizeof(reqType),
  1976.             &actualSize);
  1977.  
  1978.     if (tempErr!=noErr)
  1979.         reqType = typeChar;
  1980.  
  1981.     if (myErr == noErr)
  1982.         myErr = GotRequiredParams(theAppleEvent);
  1983.  
  1984.     /* get the data */
  1985.     if (myErr == noErr)
  1986.         myErr = HandleGetData(&myDirObj, reqType, &myDataDesc);
  1987.  
  1988.     /* evaluate size of data and discard, create desc for size */
  1989.     if (myErr == noErr)
  1990.         if (myDataDesc.dataHandle) {
  1991.             dataSize = GetHandleSize((Handle)myDataDesc.dataHandle);
  1992.             DisposHandle((Handle)myDataDesc.dataHandle);
  1993.             myErr  = AECreateDesc(typeLongInteger, (Ptr)&dataSize, sizeof(dataSize), &myDataDesc);
  1994.         }
  1995.  
  1996.  
  1997.     /* if they wanted a reply, attach it now */
  1998.  
  1999.     if (myErr==noErr)
  2000.         if (reply->descriptorType != typeNull)
  2001.             myErr = AEPutParamDesc(reply, keyDirectObject, &myDataDesc);
  2002.  
  2003.     /* discard our copy */
  2004.  
  2005.     if (myDataDesc.dataHandle)
  2006.         tempErr = AEDisposeDesc(&myDataDesc);
  2007.  
  2008.     if (myDirObj.dataHandle)
  2009.         tempErr = AEDisposeDesc(&myDirObj);
  2010.  
  2011.     return myErr;
  2012. }    /* DoGetDataSize */
  2013.  
  2014. /** -----------------------------------------------------------------------
  2015.         Name:         DoNewElement
  2016.         Purpose:        Handles the NewElement AppleEvent. Only Creates windows for
  2017.                     now.
  2018.      -----------------------------------------------------------------------**/
  2019.  
  2020. pascal OSErr DoNewElement(
  2021.     const AppleEvent *theAppleEvent,
  2022.     AppleEvent *reply,
  2023.     long       handlerRefCon)
  2024. {
  2025. #pragma unused (handlerRefCon)
  2026.  
  2027.     OSErr       myErr;
  2028.     OSErr       ignoreErr;
  2029.     DescType      returnedType;
  2030.     DescType      newElemClass;
  2031.     Size        actSize;
  2032.     AEDesc        wndwObjSpec;
  2033.     DPtr        theDoc;
  2034.  
  2035.     wndwObjSpec.dataHandle = nil;
  2036.  
  2037.     myErr =
  2038.         AEGetParamPtr(
  2039.             theAppleEvent,
  2040.             keyAEObjectClass,
  2041.             typeType,
  2042.             &returnedType,
  2043.             (Ptr)&newElemClass,
  2044.             sizeof(newElemClass),
  2045.             &actSize);
  2046.  
  2047.   /* check for missing required parameters */
  2048.  
  2049.   if (myErr == noErr)
  2050.         myErr = GotRequiredParams(theAppleEvent);
  2051.  
  2052.   /* got all required params */
  2053.  
  2054.   /* let's make sure container is the null desc */
  2055.   /* and they want a window */
  2056.  
  2057.   if (newElemClass != cWindow)
  2058.     myErr = errAEWrongDataType;
  2059.  
  2060.   /* let's create a new window */
  2061.  
  2062.     if (myErr == noErr)
  2063.         theDoc = NewDocument(false, kDocumentWindow);
  2064.  
  2065.     if (myErr==noErr)
  2066.         if (theDoc == nil)
  2067.             myErr = -1700;
  2068.         else {
  2069.             DoShowWindow(theDoc->theWindow);
  2070.             theDoc->dirty = false;
  2071.  
  2072.             myErr = MakeWindowObj(theDoc->theWindow, &wndwObjSpec);
  2073.         }
  2074.  
  2075.     if (myErr == noErr)
  2076.         if (reply->descriptorType != typeNull)
  2077.              myErr = AEPutParamDesc(reply, keyDirectObject, &wndwObjSpec);
  2078.  
  2079.     if (wndwObjSpec.dataHandle)
  2080.         ignoreErr = AEDisposeDesc(&wndwObjSpec);
  2081.  
  2082.       return myErr;
  2083. }    /* DoNewElement */
  2084.  
  2085. /** -----------------------------------------------------------------------
  2086.         Name:         DoIsThereA
  2087.         Purpose:        Handles the IsThereA AppleEvent.
  2088.      -----------------------------------------------------------------------**/
  2089.  
  2090. pascal OSErr DoIsThereA(
  2091.     const AppleEvent *theAppleEvent,
  2092.     AppleEvent       *reply,
  2093.     long             handlerRefCon)
  2094. /*
  2095.     Support check of Windows at first
  2096.  
  2097.     What we do :
  2098.         Get Direct Object
  2099.         Check have all required params
  2100.         Coerce into things we support
  2101.         if we get something back
  2102.             check to see it exists and set reply
  2103.         clean up
  2104.         return
  2105. */
  2106. {
  2107. #pragma unused (handlerRefCon)
  2108.  
  2109.     OSErr         myErr;
  2110.     OSErr         ignoreErr;
  2111.     AEDesc        myDirObject;
  2112.     AEDesc        windDesc;
  2113.     AEDesc        dataDesc;
  2114.     WindowToken   theWindowToken;
  2115.     Size          tokenSize;
  2116.     Boolean       exists;
  2117.  
  2118.     myDirObject.dataHandle = nil;
  2119.     windDesc.dataHandle    = nil;
  2120.     dataDesc.dataHandle    = nil;
  2121.  
  2122.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObject);
  2123.  
  2124.     /* check for missing required parameters */
  2125.  
  2126.     if (myErr == noErr)
  2127.         myErr = GotRequiredParams(theAppleEvent);
  2128.  
  2129.     /* got all required params */
  2130.  
  2131.     /* let's make sure they want to check for a window */
  2132.  
  2133.     exists = false;
  2134.  
  2135.     if (myErr == noErr)
  2136.         if (AECoerceDesc(&myDirObject, typeMyWndw, &windDesc)==noErr)
  2137.             if (windDesc.descriptorType!=typeNull) {
  2138.                 GetRawDataFromDescriptor(
  2139.                     &windDesc,
  2140.                     (Ptr)&theWindowToken,
  2141.                     sizeof(theWindowToken),
  2142.                     &tokenSize);
  2143.  
  2144.                 exists = (theWindowToken != nil);
  2145.             }
  2146.  
  2147.     if (myErr == noErr)
  2148.         myErr = AECreateDesc(typeBoolean, (Ptr)&exists, sizeof(exists), &dataDesc);
  2149.  
  2150.     /*
  2151.         if they wanted a reply, which they surely must,
  2152.         attach the result to it…
  2153.     */
  2154.  
  2155.     if (myErr == noErr)
  2156.         if (reply->descriptorType != typeNull)
  2157.              myErr = AEPutParamDesc(reply, keyDirectObject, &dataDesc);
  2158.  
  2159.     if (dataDesc.dataHandle)
  2160.         ignoreErr = AEDisposeDesc(&dataDesc);
  2161.  
  2162.     if (myDirObject.dataHandle)
  2163.         ignoreErr = AEDisposeDesc(&myDirObject);
  2164.  
  2165.     if (windDesc.dataHandle)
  2166.         ignoreErr = AEDisposeDesc(&windDesc);
  2167.  
  2168.     return myErr;
  2169. }    /* DoIsThereA */
  2170.  
  2171. /** -----------------------------------------------------------------------
  2172.         Name:         DoCloseWindow
  2173.         Purpose:        Handles the Close AppleEvent.
  2174.      -----------------------------------------------------------------------**/
  2175.  
  2176. pascal OSErr DoCloseWindow(
  2177.     const AppleEvent *theAppleEvent,
  2178.     AppleEvent       *reply,
  2179.     long             handlerRefCon)
  2180. {
  2181. #pragma unused (reply, handlerRefCon)
  2182.  
  2183.     OSErr         myErr;
  2184.     OSErr         tempErr;
  2185.     AEDesc        myDirObj;
  2186.     AEDesc        newDesc;
  2187.     WindowToken   theWindowToken;
  2188.     Size          tokenSize;
  2189.     DescType      saveOpt;
  2190.     Size          actSize;
  2191.     DescType      returnedType;
  2192.     DPtr          myDPtr;
  2193.  
  2194.     myDirObj.dataHandle = nil;
  2195.  
  2196.     /* pick up the direct object, which is the object (window) to close */
  2197.  
  2198.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2199.  
  2200.     /* pick up optional save param, if any */
  2201.  
  2202.     saveOpt = kAEAsk; /* the default */
  2203.  
  2204.     tempErr =
  2205.         AEGetParamPtr(
  2206.             theAppleEvent,
  2207.             keyAESaveOptions,
  2208.             typeEnumerated,
  2209.             &returnedType,
  2210.             (Ptr)&saveOpt,
  2211.             sizeof(saveOpt),
  2212.             &actSize);
  2213.  
  2214.     if (myErr == noErr)
  2215.         myErr = GotRequiredParams(theAppleEvent);
  2216.  
  2217.     /* get the window to close as a window ptr */
  2218.     if (myErr == noErr)
  2219.         if (!AECoerceDesc(&myDirObj, typeMyWndw, &newDesc))
  2220.             if (newDesc.descriptorType!=typeNull)  {
  2221.                 GetRawDataFromDescriptor(
  2222.                     &newDesc,
  2223.                     (Ptr)&theWindowToken,
  2224.                     sizeof(theWindowToken),
  2225.                     &tokenSize);
  2226.  
  2227.                 myErr = AEDisposeDesc(&newDesc);
  2228.  
  2229.                 if (theWindowToken) {
  2230.                     myErr=AESetInteractionAllowed(kAEInteractWithAll); /* Should do this in prefs */
  2231.  
  2232.                     /*
  2233.                         We do some of the close checks here to avoid
  2234.                         calling AEInteractWithUser
  2235.                     */
  2236.                     myDPtr = DPtrFromWindowPtr(theWindowToken);
  2237.                     if (myDPtr->kind == kDocumentWindow && (myDPtr->dirty || !myDPtr->u.reg.everSaved))
  2238.                         if (saveOpt != kAENo) /* Don't flip layers if force no ask */
  2239.                             myErr = AEInteractWithUser(kAEDefaultTimeout, nil, nil);
  2240.  
  2241.                     if (myErr==noErr)
  2242.                         myErr = DoClose(theWindowToken, true, saveOpt);
  2243.                 } else
  2244.                     myErr =  errAEIllegalIndex;
  2245.             }
  2246.  
  2247.     if (myDirObj.dataHandle)
  2248.         tempErr = AEDisposeDesc(&myDirObj);
  2249.  
  2250.     return myErr;
  2251. }    /* DoCloseWindow */
  2252.  
  2253. /** -----------------------------------------------------------------------
  2254.         Name:             DoSaveWindow
  2255.         Purpose:        Handles the Save AppleEvent.
  2256.      -----------------------------------------------------------------------**/
  2257.  
  2258. pascal OSErr DoSaveWindow(
  2259.     const AppleEvent *theAppleEvent,
  2260.     AppleEvent       *reply,
  2261.     long             handlerRefCon)
  2262. {
  2263. #pragma unused (reply, handlerRefCon)
  2264.  
  2265.     OSErr         myErr;
  2266.     OSErr         tempErr;
  2267.     AEDesc        myDirObj;
  2268.     AEDesc        newDesc;
  2269.     WindowToken   theWindowToken;
  2270.     Size          tokenSize;
  2271.     Size          actSize;
  2272.     DescType      returnedType;
  2273.     DPtr          theDoc;
  2274.     FSSpec        destFSSpec;
  2275.  
  2276.     myDirObj.dataHandle = nil;
  2277.  
  2278.     /* pick up the direct object, which is the window to save */
  2279.  
  2280.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard,  &myDirObj);
  2281.  
  2282.     /* pick up optional destination param, if any */
  2283.  
  2284.     tempErr =
  2285.         AEGetParamPtr(
  2286.             theAppleEvent,
  2287.             keyAEDestination,
  2288.               typeFSS,
  2289.             &returnedType,
  2290.             (Ptr)&destFSSpec,
  2291.             sizeof(destFSSpec),
  2292.             &actSize);
  2293.  
  2294.     if (myErr == noErr)
  2295.         myErr = GotRequiredParams(theAppleEvent);
  2296.  
  2297.     /* get the data */
  2298.  
  2299.     myErr = AECoerceDesc(&myDirObj, typeMyWndw, &newDesc);
  2300.  
  2301.     if (myErr == noErr)
  2302.         if (newDesc.descriptorType!=typeNull) {
  2303.             GetRawDataFromDescriptor(
  2304.                 &newDesc,
  2305.                 (Ptr)&theWindowToken,
  2306.                 sizeof(theWindowToken),
  2307.                 &tokenSize);
  2308.  
  2309.             myErr = AEDisposeDesc(&newDesc);
  2310.  
  2311.             if (theWindowToken) {
  2312.                 theDoc = DPtrFromWindowPtr(theWindowToken);
  2313.  
  2314.                 if (theDoc->kind != kDocumentWindow || theDoc->u.reg.everSaved == false)
  2315.                     if (tempErr != noErr)
  2316.                          /* We had no supplied destination and no default either */
  2317.                         myErr = kAEGenericErr;
  2318.  
  2319.                 if (myErr==noErr)
  2320.                     if (tempErr==noErr) { /* we were told where */
  2321.                         myErr = DoSave(theDoc, destFSSpec);
  2322.  
  2323.                         if (myErr==noErr)
  2324.                             AssocAllSections(theDoc);
  2325.                     } else
  2326.                         myErr = SaveUsingTemp(theDoc);
  2327.             } else
  2328.                 myErr =  errAEIllegalIndex;
  2329.         }
  2330.  
  2331.     if (myDirObj.dataHandle)
  2332.         tempErr = AEDisposeDesc(&myDirObj);
  2333.  
  2334.     return myErr;
  2335. }    /* DoSaveWindow */
  2336.  
  2337. /** -----------------------------------------------------------------------
  2338.         Name:         DoRevertWindow
  2339.         Purpose:        Handles the Revert AppleEvent.
  2340.      -----------------------------------------------------------------------**/
  2341.  
  2342. pascal OSErr DoRevertWindow(
  2343.     const AppleEvent *theAppleEvent,
  2344.     AppleEvent       *reply,
  2345.     long             handlerRefCon)
  2346. {
  2347. #pragma unused (reply, handlerRefCon)
  2348.  
  2349.     OSErr          myErr;
  2350.     OSErr          ignoreErr;
  2351.     AEDesc         myDirObj;
  2352.     AEDesc         newDesc;
  2353.     WindowToken    theWindowToken;
  2354.     Size           tokenSize;
  2355.     DPtr           theDoc;
  2356.  
  2357.     myDirObj.dataHandle = nil;
  2358.  
  2359.   /* pick up the direct object, which is the window to save */
  2360.  
  2361.       if (myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj))
  2362.           return myErr;
  2363.  
  2364.       GotRequiredParams(theAppleEvent);
  2365.  
  2366.   /* get the window to revert from the direct object */
  2367.  
  2368.     myErr = AECoerceDesc(&myDirObj, typeMyWndw, &newDesc);
  2369.  
  2370.       if (myErr == noErr)
  2371.         if (newDesc.descriptorType!=typeNull) {
  2372.             GetRawDataFromDescriptor(
  2373.                 &newDesc,
  2374.                 (Ptr)&theWindowToken,
  2375.                 sizeof(theWindowToken),
  2376.                 &tokenSize);
  2377.  
  2378.             myErr = AEDisposeDesc(&newDesc);
  2379.  
  2380.             if (theWindowToken) {
  2381.                 theDoc = DPtrFromWindowPtr(theWindowToken);
  2382.  
  2383.                 if (theDoc->kind != kDocumentWindow)
  2384.                     myErr = errAEEventNotHandled;
  2385.                 else {
  2386.                     HidePen();
  2387.                     TESetSelect(0, (*(theDoc->theText))->teLength, theDoc->theText);
  2388.                     ShowPen();
  2389.                     TEDelete(theDoc->theText);
  2390.     
  2391.                     if (theDoc->u.reg.everSaved) {
  2392.                         myErr = GetFileContents(theDoc->theFSSpec, theDoc);
  2393.                         if (myErr == noErr) {
  2394.                             ResizeWindow(theDoc);
  2395.                             theDoc->dirty = false;
  2396.                         }
  2397.                     }
  2398.     
  2399.                     DoShowWindow(theDoc->theWindow); /* <<< Visible already??? */
  2400.                     DoUpdate(theDoc);
  2401.                 }
  2402.             } else
  2403.                 myErr =  errAEIllegalIndex;
  2404.         }
  2405.  
  2406.     if (myDirObj.dataHandle)
  2407.         ignoreErr = AEDisposeDesc(&myDirObj);
  2408.  
  2409.   return myErr;
  2410. }    /* DoRevertWindow */
  2411.  
  2412. #endif
  2413.  
  2414. /**-----------------------------------------------------------------------
  2415.         Name:         DoPrintDocuments
  2416.         Purpose:        Print a list of documents (or windows).
  2417. -----------------------------------------------------------------------**/
  2418. pascal OSErr DoPrintDocuments(
  2419.     const AppleEvent *message,
  2420.    AppleEvent       *reply,
  2421.     long refcon)
  2422. {
  2423. #pragma unused (reply, refcon)
  2424.     long          index;
  2425.     long          itemsInList;
  2426.     AEKeyword     keywd;
  2427.     OSErr         err;
  2428.     AEDescList    docList;
  2429.     Size          actSize;
  2430.     DescType      typeCode;
  2431.     FSSpec        theFSSpec;
  2432.     WindowToken   theWindowToken;
  2433.     OSErr         forgetErr;
  2434.     Boolean       talkToUser;
  2435.  
  2436.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  2437.     err = AECountItems(&docList, &itemsInList);
  2438.  
  2439.     for (index = 1; index<=itemsInList; index++)
  2440.         if (err == noErr) {
  2441.             forgetErr =
  2442.                 AEGetNthPtr(
  2443.                     &docList,
  2444.                     index,
  2445.                     typeFSS,
  2446.                     &keywd,
  2447.                     &typeCode,
  2448.                     (Ptr)&theFSSpec,
  2449.                     sizeof(theFSSpec),
  2450.                     &actSize);
  2451.  
  2452.             if (forgetErr == noErr) {
  2453.                 if (err == noErr)
  2454.                     err = IssueAEOpenDoc(theFSSpec);
  2455.  
  2456.                 if (err == noErr)
  2457.                     IssuePrintWindow(FrontWindow());
  2458.  
  2459.                 if (err == noErr)
  2460.                     IssueCloseCommand(FrontWindow());
  2461.             } else { /* wasn't a file - was it a window ? */
  2462.                 err =
  2463.                     AEGetNthPtr(
  2464.                         &docList,
  2465.                         index,
  2466.                         typeMyWndw,
  2467.                         &keywd,
  2468.                         &typeCode,
  2469.                         (Ptr)&theWindowToken,
  2470.                         sizeof(WindowToken),
  2471.                         &actSize);
  2472.  
  2473.                 talkToUser = (AEInteractWithUser(kAEDefaultTimeout, nil, nil) == noErr);
  2474.  
  2475.                 if (err == noErr)
  2476.                     PrintWindow(DPtrFromWindowPtr(theWindowToken), talkToUser);
  2477.             }
  2478.         }
  2479.  
  2480.     if (docList.dataHandle)
  2481.         forgetErr = AEDisposeDesc(&docList);
  2482.  
  2483.     return err;
  2484. } /* DoPrintDocuments */
  2485.  
  2486. #ifndef RUNTIME
  2487.  
  2488. /**-----------------------------------------------------------------------
  2489.         Name:         HandleCreatePub
  2490.         Purpose:        Create a publisher.
  2491. -----------------------------------------------------------------------**/
  2492. pascal OSErr HandleCreatePub(
  2493.     const AppleEvent *theAppleEvent,
  2494.    AppleEvent       *reply,
  2495.     long refcon)
  2496. {
  2497. #pragma unused (reply, refcon)
  2498.  
  2499.     OSErr       myErr;
  2500.     FSSpec      theFSSpec;
  2501.     OSErr       forgetErr;
  2502.     OSErr       forget2Err;
  2503.     AEDesc      myDirObj;
  2504.     AEDesc      myFileLoc;
  2505.     TextToken   theTextToken;
  2506.     DPtr        theDoc;
  2507.     AEDesc      newDesc;
  2508.     long        tokenSize;
  2509.     Boolean     haveFSSpec;
  2510.  
  2511.     myErr = noErr;
  2512.  
  2513.     forgetErr  = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2514.     forget2Err = AEGetParamDesc(theAppleEvent, keyAEEditionFileLoc, typeWildCard, &myFileLoc);
  2515.  
  2516.     if (myErr==noErr)
  2517.         myErr = GotRequiredParams(theAppleEvent);
  2518.  
  2519.     if (forgetErr==noErr) { /* Set the selection to the supplied object - if any */
  2520.         forgetErr = AECoerceDesc(&myDirObj, typeMyText, &newDesc);
  2521.         if (newDesc.descriptorType!=typeNull) {
  2522.             GetRawDataFromDescriptor(&newDesc,
  2523.                                                              (Ptr)&theTextToken,
  2524.                                                              sizeof(theTextToken),
  2525.                                                              &tokenSize);
  2526.  
  2527.             theDoc = DPtrFromWindowPtr(theTextToken.tokenWindow);
  2528.  
  2529.             TESetSelect(theTextToken.tokenOffset-1,
  2530.                                     theTextToken.tokenOffset+
  2531.                                                         theTextToken.tokenLength-1,
  2532.                                     theDoc->theText);
  2533.  
  2534.             forgetErr = AEDisposeDesc(&newDesc);
  2535.         }
  2536.     } else
  2537.         theDoc = DPtrFromWindowPtr(FrontWindow());
  2538.  
  2539.     if (theDoc==nil) {
  2540.         /* Should clean up and exit with error */
  2541.     }
  2542.  
  2543.     haveFSSpec = false;
  2544.  
  2545.     if (forget2Err==noErr) { /* Get the Edition Container File */
  2546.         forget2Err = AECoerceDesc(&myDirObj,typeFSS,&newDesc);
  2547.         if (newDesc.descriptorType!=typeNull) {
  2548.             GetRawDataFromDescriptor(&newDesc, (Ptr)&theFSSpec, sizeof(theFSSpec), &tokenSize);
  2549.             forget2Err = AEDisposeDesc(&newDesc);
  2550.             haveFSSpec = true;
  2551.         }
  2552.     }
  2553.  
  2554.     if (haveFSSpec==false)
  2555.         myErr = GetEditionContainer(theDoc, &theFSSpec);
  2556.  
  2557.     if (myErr == noErr)
  2558.         myErr = PublishText(theDoc, &theFSSpec);
  2559.  
  2560.     if (myDirObj.dataHandle)
  2561.         forgetErr = AEDisposeDesc(&myDirObj);
  2562.  
  2563.     if (myFileLoc.dataHandle)
  2564.         forgetErr = AEDisposeDesc(&myFileLoc);
  2565.  
  2566.     return myErr;
  2567. } /* HandleCreatePub */
  2568.  
  2569.  
  2570. pascal OSErr MyCountProc(
  2571.     DescType desiredType,
  2572.     DescType containerClass,
  2573.     const AEDesc *container,
  2574.     long *result);
  2575.  
  2576. /** -----------------------------------------------------------------------
  2577.         Name:       HandleNumberOfElements
  2578.         Purpose:        Handles the Number Of Elements AppleEvent.
  2579.      -----------------------------------------------------------------------**/
  2580.  
  2581. pascal OSErr HandleNumberOfElements(
  2582.     const AppleEvent *theAppleEvent,
  2583.     AppleEvent *reply,
  2584.     long       handlerRefCon)
  2585. {
  2586. #pragma unused (handlerRefCon)
  2587.  
  2588.       OSErr    myErr;
  2589.       OSErr    forgetErr;
  2590.     AEDesc   myDirObj;
  2591.     DescType myClass;
  2592.     long     myCount;
  2593.     DescType returnedType;
  2594.     Size     actSize;
  2595.  
  2596.     myErr                        = errAEEventNotHandled;
  2597.     myDirObj.dataHandle     = nil;
  2598.  
  2599.     /* pick up direct object, which is the container in which things are to be counted */
  2600.  
  2601.     myErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &myDirObj);
  2602.  
  2603.     /* now the class of objects to be counted */
  2604.  
  2605.     myErr =
  2606.         AEGetParamPtr(
  2607.             theAppleEvent,
  2608.             keyAEObjectClass,
  2609.             typeType,
  2610.             &returnedType,
  2611.             (Ptr)&myClass,
  2612.             sizeof(myClass),
  2613.             &actSize);
  2614.  
  2615.     /* missing any parameters? */
  2616.  
  2617.     myErr = GotRequiredParams(theAppleEvent);
  2618.  
  2619.     /* now count */
  2620.  
  2621.     if (myErr == noErr)
  2622.         myErr = MyCountProc(myClass,myDirObj.descriptorType, &myDirObj,&myCount);
  2623.  
  2624.     /* add result to reply */
  2625.  
  2626.     if (myErr == noErr)
  2627.         if (reply->descriptorType != typeNull)
  2628.              myErr  =
  2629.                  AEPutParamPtr(
  2630.                     reply,
  2631.                     keyDirectObject,
  2632.                     typeLongInteger,
  2633.                     (Ptr)&myCount,
  2634.                     sizeof(myCount));
  2635.     if (myErr == noErr)
  2636.         forgetErr  = AEDisposeDesc(&myDirObj);
  2637.  
  2638.     return myErr;
  2639. }    /* HandleNumberOfElements */
  2640.  
  2641. /** -----------------------------------------------------------------------
  2642.         Name:             HandleShowSelection
  2643.         Purpose:        Handles the Make Selection Visible AppleEvent.
  2644.      -----------------------------------------------------------------------**/
  2645.  
  2646. pascal OSErr HandleShowSelection(
  2647.     const AppleEvent *theAppleEvent,
  2648.     AppleEvent       *reply,
  2649.     long             handlerRefCon)
  2650. {
  2651. #pragma unused (reply,handlerRefCon)
  2652.  
  2653.     OSErr       myErr;
  2654.     OSErr       ignoreErr;
  2655.     AEDesc      myDirObj;
  2656.     AEDesc      newDesc;
  2657.     AEDesc      tokenDesc;
  2658.     Size        actSize;
  2659.     WindowToken theWindowToken;
  2660.     DPtr        theDocument;
  2661.     TEHandle    theHTE;
  2662.  
  2663.     myErr      = errAEEventNotHandled;
  2664.     myDirObj.dataHandle  = nil;
  2665.     tokenDesc.dataHandle = nil;
  2666.  
  2667.     /*
  2668.         pick up direct object, i.e. the window in which to show the selection
  2669.     */
  2670.  
  2671.     myErr  =
  2672.         AEGetParamDesc(
  2673.             theAppleEvent,
  2674.             keyDirectObject,
  2675.             typeWildCard,
  2676.             &myDirObj);
  2677.  
  2678.     /*
  2679.         missing any parameters?
  2680.     */
  2681.  
  2682.     myErr = GotRequiredParams(theAppleEvent);
  2683.  
  2684.     /*
  2685.         convert object to WindowToken which we understand
  2686.     */
  2687.     myErr = AEResolve(&myDirObj, kAEIDoMinimum, &tokenDesc);
  2688.  
  2689.     if (myErr == noErr)
  2690.         if (tokenDesc.descriptorType==typeMyWndw) {
  2691.             if (AECoerceDesc(&myDirObj, typeMyWndw, &newDesc) == noErr) {
  2692.                 GetRawDataFromDescriptor(
  2693.                     &newDesc,
  2694.                     (Ptr)&theWindowToken,
  2695.                     sizeof(theWindowToken),
  2696.                     &actSize);
  2697.  
  2698.                 ignoreErr = AEDisposeDesc(&newDesc);
  2699.  
  2700.                 if (myErr==noErr)
  2701.                     if (theWindowToken)
  2702.                         ShowSelect(DPtrFromWindowPtr(theWindowToken));
  2703.                     else
  2704.                         myErr = errAEIllegalIndex;
  2705.             }
  2706.         } else if (tokenDesc.descriptorType==typeMyText) {
  2707.             myErr =
  2708.                 SetSelectionOfAppleEventObject(
  2709.                     keyDirectObject,
  2710.                     theAppleEvent,
  2711.                     &theDocument,
  2712.                     &theHTE);
  2713.  
  2714.             if (theDocument)
  2715.               ShowSelect(theDocument);
  2716.             else
  2717.                 myErr = errAEIllegalIndex;
  2718.         } else
  2719.             myErr = errAEEventNotHandled;
  2720.  
  2721.     if (myDirObj.dataHandle)
  2722.         ignoreErr = AEDisposeDesc(&myDirObj);
  2723.  
  2724.     if (tokenDesc.dataHandle)
  2725.         ignoreErr = AEDisposeDesc(&tokenDesc);
  2726.  
  2727.     return myErr;
  2728. }    /* HandleShowSelection */
  2729.  
  2730. pascal OSErr HandleStartRecording(
  2731.     const AppleEvent *theAppleEvent,
  2732.     AppleEvent *reply,
  2733.     long       handlerRefCon)
  2734. {
  2735. #pragma unused (reply,handlerRefCon)
  2736.  
  2737.     OSErr myErr;
  2738.  
  2739.     gBigBrother++;
  2740.  
  2741.     myErr = GotRequiredParams(theAppleEvent);
  2742.  
  2743.     return myErr;
  2744.  
  2745. }    /* HandleStartRecording */
  2746.  
  2747. pascal OSErr HandleStopRecording(
  2748.     const AppleEvent *theAppleEvent,
  2749.     AppleEvent *reply,
  2750.     long handlerRefCon)
  2751. {
  2752. #pragma unused (theAppleEvent,reply,handlerRefCon)
  2753.  
  2754.     gBigBrother--;
  2755.     return noErr;
  2756. }    /* HandleStopRecording */
  2757.  
  2758.  
  2759. #pragma segment AECommandIssuers
  2760.  
  2761. /*******************************************************************************/
  2762. /*
  2763.         Start of section involved in building and sending AppleEvent Objects as/with
  2764.         commands
  2765.  */
  2766.  
  2767. /*
  2768.     Make an AEDesc that describes the selection in the window and text edit
  2769.     record supplied
  2770. */
  2771.  
  2772. pascal OSErr MakeWindowObj(
  2773.     WindowPtr theWindow,
  2774.     AEDesc    *dMyDoc)
  2775. {
  2776.     AEDesc   dNull;
  2777.     AEDesc   dDocName;
  2778.     Str255   windowName;
  2779.     OSErr    myErr;
  2780.  
  2781.     GetWTitle(theWindow, windowName);
  2782.     myErr = AECreateDesc(typeChar,(Ptr)&windowName[1], windowName[0], &dDocName);
  2783.  
  2784.     if (myErr==noErr)
  2785.         myErr = AECreateDesc(typeNull, nil , 0, &dNull);
  2786.  
  2787.     if (myErr==noErr)
  2788.         myErr = CreateObjSpecifier(cWindow, &dNull, formName, &dDocName, true, dMyDoc);
  2789.  
  2790.     return myErr;
  2791. } /*MakeWindowObj*/
  2792.  
  2793. pascal OSErr MakeTextObj(
  2794.     WindowPtr theWindow,
  2795.     short     selStart,
  2796.     short     selEnd,
  2797.     AEDesc    *selTextObj)
  2798. {
  2799.     OSErr    myErr;
  2800.     OSErr    ignoreErr;
  2801.     AEDesc   dMyDoc;
  2802.     AEDesc   startOfs;
  2803.     AEDesc   endOfs;
  2804.     AEDesc   startObj;
  2805.     AEDesc   endObj;
  2806.     AEDesc   rangeDesc;
  2807.     long     startChar;
  2808.     long     endChar;
  2809.     Boolean  spotFlag;
  2810.  
  2811.     myErr = noErr;
  2812.  
  2813.     if (theWindow==nil)
  2814.         return noErr;
  2815.  
  2816.     selTextObj->dataHandle = nil;
  2817.     dMyDoc.dataHandle      = nil;
  2818.     startObj.dataHandle    = nil;
  2819.     endObj.dataHandle      = nil;
  2820.  
  2821.     /*
  2822.         make the window object
  2823.     */
  2824.  
  2825.     if (myErr = MakeWindowObj(theWindow, &dMyDoc))
  2826.         return myErr;
  2827.  
  2828.     /* get the start and end of selection */
  2829.  
  2830.     startChar = selStart+1;    /* start counting obj's from 1, not 0 */
  2831.     endChar   = selEnd;
  2832.     spotFlag  = (selStart == selEnd);
  2833.  
  2834.     if (myErr = CreateOffsetDescriptor(startChar, &startOfs))
  2835.         return noErr;
  2836.  
  2837.     if (spotFlag)
  2838.         myErr =
  2839.             CreateObjSpecifier(
  2840.                 cSpot,
  2841.                 &dMyDoc,
  2842.                 formAbsolutePosition,
  2843.                 &startOfs,
  2844.                 true,
  2845.                 selTextObj);
  2846.     else {
  2847.         /* not a spot - must represent as range */
  2848.         /* make obj for start char */
  2849.  
  2850.         myErr =
  2851.             CreateObjSpecifier(
  2852.                 cChar,
  2853.                 &dMyDoc,
  2854.                 formAbsolutePosition,
  2855.                 &startOfs,
  2856.                 false,
  2857.                 &startObj);
  2858.  
  2859.         if (myErr==noErr)
  2860.             myErr = CreateOffsetDescriptor(endChar, &endOfs);
  2861.  
  2862.         if (myErr==noErr)
  2863.             myErr =
  2864.                 CreateObjSpecifier(
  2865.                     cChar,
  2866.                     &dMyDoc,
  2867.                     formAbsolutePosition,
  2868.                     &endOfs,
  2869.                     false,
  2870.                     &endObj);
  2871.  
  2872.         if (myErr==noErr)
  2873.             myErr = CreateRangeDescriptor(&startObj, &endObj, false, &rangeDesc);
  2874.  
  2875.         if (myErr==noErr)
  2876.             myErr = CreateObjSpecifier(cChar, &dMyDoc, formRange, &rangeDesc, true, selTextObj);
  2877.  
  2878.         if (startObj.dataHandle)
  2879.           ignoreErr = AEDisposeDesc(&startObj);
  2880.  
  2881.         if (startOfs.dataHandle)
  2882.           ignoreErr = AEDisposeDesc(&startOfs);
  2883.  
  2884.         if (endObj.dataHandle)
  2885.           ignoreErr = AEDisposeDesc(&endObj);
  2886.  
  2887.         if (endOfs.dataHandle)
  2888.           ignoreErr = AEDisposeDesc(&endOfs);
  2889.     }
  2890.  
  2891.     return myErr;
  2892. }
  2893.  
  2894. pascal OSErr MakeSelectedTextObj(
  2895.     WindowPtr theWindow,
  2896.     TEHandle  theTextEditHandle,
  2897.     AEDesc    *selTextObj)
  2898. {
  2899.     return
  2900.         MakeTextObj(
  2901.             theWindow,
  2902.             (**theTextEditHandle).selStart,
  2903.             (**theTextEditHandle).selEnd,
  2904.             selTextObj);
  2905.  
  2906. }    /* MakeSelectedTextObj */
  2907.  
  2908. enum editCommandType {
  2909. editCutCommand   = 1,
  2910. editCopyCommand  = 2,
  2911. editPasteCommand = 3,
  2912. editClearCommand = 4
  2913. };
  2914.  
  2915. typedef enum editCommandType editCommandType;
  2916.  
  2917. pascal void DoEditCommand(DPtr theDocument,editCommandType whatCommand)
  2918. {
  2919.       OSErr         err;
  2920.       OSErr         forgetErr;
  2921.     AEAddressDesc ourAddress;
  2922.     AppleEvent    editCommandEvent;
  2923.     AppleEvent    ignoreReply;
  2924.     AEDesc        ourTextSelObj;
  2925.     AEEventID     theEventID;
  2926.     AEEventClass  theEventClass;
  2927.  
  2928.     /*
  2929.             Initialise
  2930.     */
  2931.  
  2932.     ourAddress.dataHandle             = nil;
  2933.     ourTextSelObj.dataHandle         = nil;
  2934.     editCommandEvent.dataHandle     = nil;
  2935.     ignoreReply.dataHandle             = nil;
  2936.  
  2937.     err = MakeSelfAddress(&ourAddress);
  2938.  
  2939.     /*
  2940.         Build an object to represent the current document's selection
  2941.     */
  2942.     err = MakeSelectedTextObj(theDocument->theWindow, theDocument->theText, &ourTextSelObj);
  2943.  
  2944.     if (err==noErr) {
  2945.         switch (whatCommand) {
  2946.         case  editCutCommand:
  2947.             theEventID    = kAECut;
  2948.             theEventClass = kAEMiscStandards;
  2949.             break;
  2950.         case  editCopyCommand:
  2951.             theEventID    = kAECopy;
  2952.             theEventClass = kAEMiscStandards;
  2953.             break;
  2954.         case  editPasteCommand:
  2955.             theEventID    = kAEPaste;
  2956.             theEventClass = kAEMiscStandards;
  2957.             break;
  2958.         case  editClearCommand:
  2959.             theEventID    = kAEDelete;
  2960.             theEventClass = kAECoreSuite;
  2961.             break;
  2962.         }
  2963.  
  2964.         err = AECreateAppleEvent( theEventClass, theEventID, &ourAddress, 0, 0, &editCommandEvent);
  2965.  
  2966.         /* add parameter */
  2967.         if (err==noErr)
  2968.             err = AEPutParamDesc(&editCommandEvent, keyDirectObject, &ourTextSelObj);
  2969.  
  2970.         /*and now Send the message*/
  2971.         if (err==noErr)
  2972.             err = AESend(&editCommandEvent,&ignoreReply,kAENoReply,kAEHighPriority,10000,nil, nil);
  2973.     }
  2974.  
  2975.     /*
  2976.         Clean up
  2977.     */
  2978.     if (ourAddress.dataHandle)
  2979.         forgetErr = AEDisposeDesc(&ourAddress);
  2980.  
  2981.     if (editCommandEvent.dataHandle)
  2982.         forgetErr = AEDisposeDesc(&editCommandEvent);
  2983.  
  2984.     if (ignoreReply.dataHandle)
  2985.         forgetErr = AEDisposeDesc(&ignoreReply);
  2986.  
  2987.     if (ourTextSelObj.dataHandle)
  2988.         forgetErr = AEDisposeDesc(&ourTextSelObj);
  2989.  
  2990. } /*DoEditCommand*/
  2991.  
  2992. #endif
  2993.  
  2994. pascal void IssueCutCommand(DPtr theDocument)
  2995. {
  2996. #ifndef RUNTIME
  2997.     DoEditCommand(theDocument, editCutCommand);
  2998. #else
  2999.     if (theDocument->kind != kDocumentWindow)
  3000.         if (    !theDocument->u.cons.selected 
  3001.             || (*theDocument->theText)->selStart < theDocument->u.cons.fence
  3002.         ) {
  3003.             if (!AllSelected(theDocument->theText)) {
  3004.                 SysBeep(1);
  3005.                 
  3006.                 IssueCopyCommand(theDocument);
  3007.                 
  3008.                 return;
  3009.             }
  3010.         }
  3011.  
  3012.     ZeroScrap();
  3013.     TECut(theDocument->theText);
  3014.     TEToScrap();
  3015.     AdjustScrollbars(theDocument, false);
  3016.     DrawPageExtras(theDocument);
  3017.     theDocument->dirty = true;
  3018. #endif
  3019. }
  3020.  
  3021. pascal void IssueCopyCommand(DPtr theDocument)
  3022. {
  3023. #ifndef RUNTIME
  3024.     DoEditCommand(theDocument, editCopyCommand);
  3025. #else
  3026.     ZeroScrap();
  3027.     TECopy(theDocument->theText);
  3028.     TEToScrap();
  3029. #endif
  3030. }
  3031.  
  3032. pascal void IssuePasteCommand(DPtr theDocument)
  3033. {
  3034. #ifndef RUNTIME
  3035.     DoEditCommand(theDocument, editPasteCommand);
  3036. #else
  3037.     if (theDocument->kind != kDocumentWindow)
  3038.         if (    !theDocument->u.cons.selected
  3039.             || (*theDocument->theText)->selStart < theDocument->u.cons.fence
  3040.         ) {
  3041.             SysBeep(1);
  3042.             
  3043.             return;
  3044.         }
  3045.     
  3046.     TEFromScrap();
  3047.     TEPaste(theDocument->theText);
  3048.     EnforceMemory(theDocument, theDocument->theText);
  3049.     AdjustScrollbars(theDocument, false);
  3050.     DrawPageExtras(theDocument);
  3051.         
  3052.     theDocument->dirty = true;
  3053. #endif
  3054. }
  3055.  
  3056. pascal void IssueClearCommand(DPtr theDocument)
  3057. {
  3058. #ifndef RUNTIME
  3059.     DoEditCommand(theDocument, editClearCommand);
  3060. #else
  3061.     if (theDocument->kind != kDocumentWindow)
  3062.         if (    !theDocument->u.cons.selected
  3063.             || (*theDocument->theText)->selStart < theDocument->u.cons.fence
  3064.         ) {
  3065.             if (!AllSelected(theDocument->theText)) {
  3066.                 SysBeep(1);
  3067.             
  3068.                 return;
  3069.             }
  3070.         }
  3071.         
  3072.     TEDelete(theDocument->theText);
  3073.     AdjustScrollbars(theDocument, false);
  3074.     DrawPageExtras(theDocument);
  3075.     theDocument->dirty = true;
  3076. #endif
  3077. }
  3078.  
  3079. /*
  3080.     Window property routines
  3081. */
  3082.  
  3083. pascal void IssueZoomCommand(WindowPtr whichWindow, short whichPart)
  3084. {
  3085. #ifndef RUNTIME
  3086.       Boolean       zoomBool;
  3087.     AEDesc        zoomDesc;
  3088.     AEAddressDesc selfAddr;
  3089.     AEDesc        frontWinObj;
  3090.     OSErr         err;
  3091.  
  3092.     err = MakeSelfAddress(&selfAddr);
  3093.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3094.  
  3095.     zoomBool = (whichPart==inZoomOut);
  3096.  
  3097.     err = AECreateDesc(typeBoolean, (Ptr)&zoomBool, sizeof(zoomBool), &zoomDesc);
  3098.     err = SendAESetObjProp(&frontWinObj, pIsZoomed, &zoomDesc, &selfAddr);
  3099. #else
  3100.     ZoomWindow(whichWindow, whichPart, false);
  3101.  
  3102.     ResizeWindow(DPtrFromWindowPtr(whichWindow));
  3103. #endif
  3104. } /* IssueZoomCommand */
  3105.  
  3106. pascal void IssueCloseCommand(WindowPtr whichWindow)
  3107. {
  3108. #ifndef RUNTIME
  3109.     AEAddressDesc  selfAddr;
  3110.     AEDesc         frontWinObj;
  3111.     OSErr          err;
  3112.     OSErr          ignoreErr;
  3113.     AppleEvent     closeCommandEvent;
  3114.     AppleEvent     ignoreReply;
  3115.  
  3116.     frontWinObj.dataHandle = nil;
  3117.  
  3118.     err = MakeSelfAddress(&selfAddr);
  3119.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3120.     err = AECreateAppleEvent( kAECoreSuite, kAEClose, &selfAddr, 0, 0, &closeCommandEvent) ;
  3121.  
  3122.     /* add parameter - the window to close */
  3123.     if (err==noErr)
  3124.         err = AEPutParamDesc(&closeCommandEvent, keyDirectObject, &frontWinObj);
  3125.  
  3126.     if (err==noErr)
  3127.         err = AESend(&closeCommandEvent,&ignoreReply,kAENoReply+kAEAlwaysInteract,kAEHighPriority,10000,nil, nil);
  3128.  
  3129.     if (closeCommandEvent.dataHandle)
  3130.         ignoreErr = AEDisposeDesc(&closeCommandEvent);
  3131.  
  3132.     if (selfAddr.dataHandle)
  3133.         ignoreErr = AEDisposeDesc(&selfAddr);
  3134.  
  3135.     if (frontWinObj.dataHandle)
  3136.         ignoreErr = AEDisposeDesc(&frontWinObj);
  3137. #else
  3138.     DoClose(whichWindow, true, kAEAsk);
  3139. #endif
  3140. } /* IssueCloseCommand */
  3141.  
  3142. pascal void IssueSizeWindow(WindowPtr whichWindow, short newHSize, short newVSize)
  3143. {
  3144. #ifndef RUNTIME
  3145.       Rect          sizeRect;
  3146.     Rect          contentRect;
  3147.     short         edgeSize;
  3148.     AEDesc        sizeDesc;
  3149.     AEAddressDesc selfAddr;
  3150.     AEDesc        frontWinObj;
  3151.     OSErr         err;
  3152.  
  3153.     sizeRect    = (**(((WindowPeek)whichWindow)->strucRgn)).rgnBBox;
  3154.     contentRect = (**(((WindowPeek)whichWindow)->contRgn)).rgnBBox;
  3155.  
  3156.     edgeSize = sizeRect.right-sizeRect.left-(contentRect.right-contentRect.left);
  3157.     sizeRect.right = sizeRect.left+newHSize+edgeSize;
  3158.  
  3159.     edgeSize = sizeRect.bottom-sizeRect.top-(contentRect.bottom-contentRect.top);
  3160.     sizeRect.bottom = sizeRect.top+newVSize+edgeSize;
  3161.  
  3162.     err = MakeSelfAddress(&selfAddr);
  3163.  
  3164.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3165.  
  3166.     if (err==noErr)
  3167.         err =
  3168.             AECreateDesc(
  3169.                 typeQDRectangle,
  3170.                 (Ptr)&sizeRect,
  3171.                 sizeof(sizeRect),
  3172.                 &sizeDesc);
  3173.  
  3174.     if (err==noErr)
  3175.         err =
  3176.             SendAESetObjProp(
  3177.                 &frontWinObj,
  3178.                 pBounds,
  3179.                 &sizeDesc,
  3180.                 &selfAddr);
  3181. #else
  3182.     ResizeWindow(DPtrFromWindowPtr(whichWindow));
  3183. #endif
  3184. } /*IssueSizeWindow*/
  3185.  
  3186. pascal void IssueMoveWindow(WindowPtr whichWindow, Rect sizeRect)
  3187. {
  3188. #ifndef RUNTIME
  3189.     AEDesc        sizeDesc;
  3190.     AEAddressDesc selfAddr;
  3191.     AEDesc        frontWinObj;
  3192.     OSErr         err;
  3193.  
  3194.     err = MakeSelfAddress(&selfAddr);
  3195.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3196.  
  3197.     if (err==noErr)
  3198.         err = AECreateDesc(typeQDRectangle, (Ptr)&sizeRect, sizeof(sizeRect), &sizeDesc);
  3199.  
  3200.     if (err==noErr)
  3201.         err = SendAESetObjProp(&frontWinObj, pBounds, &sizeDesc, &selfAddr);
  3202. #else
  3203.     /* Everything is all right already */
  3204. #endif
  3205. } /*IssueMoveWindow*/
  3206.  
  3207. pascal void IssuePageSetupWindow(WindowPtr whichWindow, TPrint thePageSetup)
  3208. {
  3209. #ifndef RUNTIME
  3210.     AEDesc        sizeDesc;
  3211.     AEAddressDesc selfAddr;
  3212.     AEDesc        frontWinObj;
  3213.     OSErr         err;
  3214.  
  3215.     err = MakeSelfAddress(&selfAddr);
  3216.  
  3217.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3218.  
  3219.     if (err==noErr)
  3220.         err = AECreateDesc(typeTPrint, (Ptr)&thePageSetup, sizeof(thePageSetup), &sizeDesc);
  3221.  
  3222.     if (err==noErr)
  3223.         err = SendAESetObjProp(&frontWinObj, pPageSetup, &sizeDesc, &selfAddr);
  3224. #else
  3225.     /* Everything is all right already */
  3226. #endif
  3227. } /*IssuePageSetupWindow*/
  3228.  
  3229. #ifndef RUNTIME
  3230. pascal void IssueShowBorders(WindowPtr whichWindow, Boolean showBorders)
  3231. {
  3232.     AEDesc        sizeDesc;
  3233.     AEAddressDesc selfAddr;
  3234.     AEDesc        frontWinObj;
  3235.     OSErr         err;
  3236.  
  3237.     err = MakeSelfAddress(&selfAddr);
  3238.  
  3239.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3240.  
  3241.     if (err==noErr)
  3242.         err = AECreateDesc(typeBoolean, (Ptr)&showBorders, sizeof(showBorders), &sizeDesc);
  3243.  
  3244.     if (err==noErr)
  3245.         err = SendAESetObjProp(&frontWinObj, pShowBorders, &sizeDesc, &selfAddr);
  3246. } /*IssueShowBorders*/
  3247. #endif
  3248.  
  3249. pascal void IssuePrintWindow(WindowPtr whichWindow)
  3250. {
  3251. #ifndef RUNTIME
  3252.     AEAddressDesc selfAddr;
  3253.     AEDesc        frontWinObj;
  3254.     OSErr         err;
  3255.     OSErr         ignoreErr;
  3256.     AppleEvent    printCommandEvent;
  3257.     AppleEvent    ignoreReply;
  3258.  
  3259.     err = MakeSelfAddress(&selfAddr);
  3260.  
  3261.     err = MakeWindowObj(whichWindow, &frontWinObj);
  3262.  
  3263.     err = AECreateAppleEvent(kCoreEventClass, kAEPrintDocuments, &selfAddr, 0, 0, &printCommandEvent) ;
  3264.  
  3265.     /*
  3266.         add parameter - the window to print
  3267.     */
  3268.  
  3269.     if (err==noErr)
  3270.         err = AEPutParamDesc(&printCommandEvent, keyDirectObject, &frontWinObj);
  3271.  
  3272.     if (err==noErr)
  3273.         err = AESend(&printCommandEvent,&ignoreReply,kAENoReply+kAEAlwaysInteract,kAEHighPriority,10000,nil, nil);
  3274.  
  3275.       if (printCommandEvent.dataHandle)
  3276.         ignoreErr = AEDisposeDesc(&printCommandEvent);
  3277.  
  3278.     if (frontWinObj.dataHandle)
  3279.         err = AEDisposeDesc(&frontWinObj);
  3280.  
  3281.     if (selfAddr.dataHandle)
  3282.         err = AEDisposeDesc(&selfAddr);
  3283. #else
  3284.     PrintWindow(DPtrFromWindowPtr(whichWindow), true);
  3285. #endif
  3286. } /*IssuePrintWindow*/
  3287.  
  3288. pascal OSErr IssueAEOpenDoc(FSSpec myFSSpec)
  3289. /* send OpenDocs AppleEvent to myself, with a one-element list
  3290.   containing the given file spec
  3291.  
  3292.   NOTES : the core AEOpenDocs event is defined as taking a list of
  3293.           aliases (not file specs) as its direct parameter.  However,
  3294.             we can send the file spec instead and depend on AppleEvents'
  3295.             automatic coercion.  In fact, we don't really even have to put
  3296.             in a list; AppleEvents will coerce a descriptor into a 1-element
  3297.             list if called for.  In this routine, though, we'll make the
  3298.             list for demonstration purposes.
  3299. */
  3300.  
  3301. {
  3302. #ifndef RUNTIME
  3303.     AppleEvent    myAppleEvent;
  3304.     AppleEvent    defReply;
  3305.     AEDescList    docList;
  3306.     AEAddressDesc selfAddr;
  3307.     OSErr         myErr;
  3308.     OSErr         ignoreErr;
  3309.  
  3310.     myAppleEvent.dataHandle = nil;
  3311.     docList.dataHandle  = nil;
  3312.     selfAddr.dataHandle = nil;
  3313.     defReply.dataHandle = nil;
  3314.  
  3315.     /*
  3316.         Create empty list and add one file spec
  3317.     */
  3318.     myErr = AECreateList(nil,0,false, &docList);
  3319.  
  3320.     if (myErr==noErr)
  3321.         myErr = AEPutPtr(&docList,1,typeFSS,(Ptr)&myFSSpec,sizeof(myFSSpec));
  3322.  
  3323.     /*
  3324.         Create a self address to send it to
  3325.     */
  3326.     if (myErr==noErr)
  3327.         myErr = MakeSelfAddress(&selfAddr);
  3328.  
  3329.     if (myErr==noErr)
  3330.         myErr =
  3331.             AECreateAppleEvent(
  3332.                 MPAppSig,
  3333.                 kAEOpenDocuments,
  3334.                 &selfAddr,
  3335.                 kAutoGenerateReturnID,
  3336.                 kAnyTransactionID,
  3337.                 &myAppleEvent);
  3338.  
  3339.     /*
  3340.         Put Params into our event and send it
  3341.     */
  3342.     if (myErr == noErr)
  3343.         myErr =
  3344.             AEPutParamDesc(
  3345.                 &myAppleEvent,
  3346.                 keyDirectObject,
  3347.                 &docList);
  3348.  
  3349.     myErr =
  3350.         AESend(
  3351.             &myAppleEvent,
  3352.             &defReply,
  3353.             kAENoReply+kAEAlwaysInteract,
  3354.             kAENormalPriority,
  3355.             kAEDefaultTimeout,
  3356.             nil,
  3357.             nil);
  3358.  
  3359.     if (selfAddr.dataHandle)
  3360.         ignoreErr = AEDisposeDesc(&selfAddr);
  3361.  
  3362.     if (myAppleEvent.dataHandle)
  3363.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3364.  
  3365.     if (docList.dataHandle)
  3366.         ignoreErr = AEDisposeDesc(&docList);
  3367.  
  3368.     return myErr;
  3369. #else
  3370.     DocType        type;
  3371.  
  3372.     switch (type = GetDocType(&myFSSpec)) {
  3373.     case kPlainTextDoc:
  3374.     case kScriptDoc:
  3375.     case kRuntime6Doc:
  3376.     case kOldRuntime6Doc:
  3377.     case kRuntime7Doc:
  3378.         return OpenOld(myFSSpec, type);
  3379.     default:
  3380.         SysBeep(1);
  3381.         
  3382.         return errAEEventNotHandled;
  3383.     }
  3384. #endif
  3385. }    /* IssueAEOpenDoc */
  3386.  
  3387. pascal void IssueAENewWindow(void)
  3388. /*
  3389.     send the New Element event to myself with a null container
  3390. */
  3391. {
  3392. #ifndef RUNTIME
  3393.     AppleEvent    myAppleEvent;
  3394.     AppleEvent    defReply;
  3395.     AEAddressDesc selfAddr;
  3396.     OSErr         myErr;
  3397.     OSErr         ignoreErr;
  3398.     DescType      elemClass;
  3399.  
  3400.     myAppleEvent.dataHandle = nil;
  3401.  
  3402.     /*
  3403.         Create the address of us
  3404.     */
  3405.  
  3406.     myErr = MakeSelfAddress(&selfAddr);
  3407.  
  3408.     /*
  3409.         create event
  3410.     */
  3411.  
  3412.     myErr =
  3413.         AECreateAppleEvent(
  3414.             kAECoreSuite,
  3415.             kAECreateElement,
  3416.             &selfAddr,
  3417.             kAutoGenerateReturnID,
  3418.             kAnyTransactionID,
  3419.             &myAppleEvent);
  3420.  
  3421.     /*
  3422.         attach desired class of new element
  3423.     */
  3424.  
  3425.     elemClass = cWindow;
  3426.  
  3427.     if (myErr == noErr)
  3428.         myErr =
  3429.             AEPutParamPtr(
  3430.                 &myAppleEvent,
  3431.                 keyAEObjectClass,
  3432.                 typeType,
  3433.                 (Ptr)&elemClass,
  3434.                 sizeof(elemClass));
  3435.  
  3436.     /*
  3437.         send the event
  3438.     */
  3439.  
  3440.     if (myErr == noErr)
  3441.         myErr =
  3442.             AESend(
  3443.                 &myAppleEvent,
  3444.                 &defReply,
  3445.                 kAENoReply+kAENeverInteract,
  3446.                 kAENormalPriority,
  3447.                 kAEDefaultTimeout,
  3448.                 nil,
  3449.                 nil);
  3450.     /*
  3451.         Clean up - reply never created so don't throw away
  3452.     */
  3453.     if (selfAddr.dataHandle)
  3454.         ignoreErr = AEDisposeDesc(&selfAddr);
  3455.  
  3456.     if (myAppleEvent.dataHandle)
  3457.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3458. #else
  3459.     DPtr    doc;
  3460.     
  3461.     doc = NewDocument(false, kDocumentWindow);
  3462.  
  3463.     if (doc)
  3464.         DoShowWindow(doc->theWindow);
  3465. #endif
  3466. }    /* IssueAENewWindow */
  3467.  
  3468. pascal OSErr IssueSaveCommand(
  3469.     WindowPtr theWindow,
  3470.     FSSpecPtr where)
  3471. /*
  3472.     send an AppleEvent Save Event to myself
  3473. */
  3474. {
  3475. #ifndef RUNTIME
  3476.     AEDesc        windowObj;
  3477.     AppleEvent    myAppleEvent;
  3478.     AppleEvent    defReply;
  3479.     OSErr         myErr;
  3480.     OSErr         ignoreErr;
  3481.     AEAddressDesc selfAddr;
  3482.  
  3483.     windowObj.dataHandle = nil;
  3484.     myAppleEvent.dataHandle = nil;
  3485.  
  3486.     myErr = MakeWindowObj(theWindow, &windowObj);
  3487.  
  3488.     if (myErr==noErr)
  3489.         myErr = MakeSelfAddress(&selfAddr);
  3490.  
  3491.   /*
  3492.         Build event
  3493.     */
  3494.   if (myErr == noErr)
  3495.         myErr =
  3496.             AECreateAppleEvent(
  3497.                 kAECoreSuite,
  3498.                 kAESave,
  3499.                 &selfAddr,
  3500.                 kAutoGenerateReturnID,
  3501.                 kAnyTransactionID,
  3502.                 &myAppleEvent);
  3503.  
  3504.   /*
  3505.         say which window
  3506.     */
  3507.   if (myErr==noErr)
  3508.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj);
  3509.  
  3510.   /*
  3511.         add optional file param if we need to
  3512.     */
  3513.   if (where)
  3514.         if (myErr==noErr)
  3515.             myErr =
  3516.                 AEPutParamPtr(
  3517.                     &myAppleEvent,
  3518.                     keyAEDestination,
  3519.                     typeFSS,
  3520.                     (Ptr)where,
  3521.                     sizeof(FSSpec));
  3522.  
  3523.   /*
  3524.         send the event
  3525.     */
  3526.   if (myErr==noErr)
  3527.         myErr  =
  3528.             AESend(
  3529.                 &myAppleEvent,
  3530.                 &defReply,
  3531.                 kAENoReply+kAENeverInteract,
  3532.                 kAENormalPriority,
  3533.                 kAEDefaultTimeout,
  3534.                 nil,
  3535.                 nil);
  3536.  
  3537.     if (selfAddr.dataHandle)
  3538.         ignoreErr = AEDisposeDesc(&selfAddr);
  3539.  
  3540.     if (windowObj.dataHandle)
  3541.         ignoreErr = AEDisposeDesc(&windowObj);
  3542.  
  3543.     if (myAppleEvent.dataHandle)
  3544.         myErr = AEDisposeDesc(&myAppleEvent);
  3545.  
  3546.     return myErr;
  3547. #else
  3548.     if (where)
  3549.         return DoSave(DPtrFromWindowPtr(theWindow), *where);
  3550.     else
  3551.         return SaveUsingTemp(DPtrFromWindowPtr(theWindow));
  3552. #endif
  3553. }    /* IssueSaveCommand */
  3554.  
  3555. pascal OSErr IssueRevertCommand(WindowPtr theWindow)
  3556. /*
  3557.     send an AppleEvent Revert Event to myself
  3558. */
  3559. {
  3560. #ifndef RUNTIME
  3561.     AEDesc        windowObj;
  3562.     AppleEvent    myAppleEvent;
  3563.     AppleEvent    defReply;
  3564.     OSErr         myErr;
  3565.     OSErr         ignoreErr;
  3566.     AEAddressDesc selfAddr;
  3567.  
  3568.     windowObj.dataHandle = nil;
  3569.     myAppleEvent.dataHandle = nil;
  3570.  
  3571.     myErr = MakeWindowObj(theWindow, &windowObj);
  3572.  
  3573.     if (myErr==noErr)
  3574.         myErr = MakeSelfAddress(&selfAddr);
  3575.  
  3576.     /*
  3577.         Build event
  3578.     */
  3579.  
  3580.     if (myErr == noErr)
  3581.         myErr  =
  3582.             AECreateAppleEvent(
  3583.                 kAEMiscStandards,
  3584.                 kAERevert,
  3585.                 &selfAddr,
  3586.                 kAutoGenerateReturnID,
  3587.                 kAnyTransactionID,
  3588.                 &myAppleEvent);
  3589.     /*
  3590.         say which window
  3591.     */
  3592.  
  3593.     if (myErr == noErr)
  3594.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, &windowObj);
  3595.     /*
  3596.         send the event
  3597.     */
  3598.     if (myErr==noErr)
  3599.         myErr =
  3600.             AESend(
  3601.                 &myAppleEvent,
  3602.                 &defReply,
  3603.                 kAENoReply+kAENeverInteract,
  3604.                 kAENormalPriority,
  3605.                 kAEDefaultTimeout,
  3606.                 nil,
  3607.                 nil);
  3608.  
  3609.     if (windowObj.dataHandle)
  3610.         ignoreErr = AEDisposeDesc(&windowObj);
  3611.  
  3612.     if (myAppleEvent.dataHandle)
  3613.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3614.  
  3615.     if (selfAddr.dataHandle)
  3616.         ignoreErr = AEDisposeDesc(&selfAddr);
  3617.  
  3618.     return myErr;
  3619. #else
  3620.     OSErr myErr;
  3621.     DPtr     theDoc = DPtrFromWindowPtr(theWindow);
  3622.  
  3623.     if (theDoc->kind != kDocumentWindow)
  3624.         return errAEEventNotHandled;
  3625.     else {
  3626.         HidePen();
  3627.         TESetSelect(0, (*(theDoc->theText))->teLength, theDoc->theText);
  3628.         ShowPen();
  3629.         TEDelete(theDoc->theText);
  3630.  
  3631.         if (theDoc->u.reg.everSaved) {
  3632.             myErr = GetFileContents(theDoc->theFSSpec, theDoc);
  3633.             if (myErr == noErr) {
  3634.                 ResizeWindow(theDoc);
  3635.                 theDoc->dirty = false;
  3636.             }
  3637.         }
  3638.  
  3639.         DoShowWindow(theDoc->theWindow); /* <<< Visible already??? */
  3640.         DoUpdate(theDoc);
  3641.         
  3642.         return noErr;
  3643.     }
  3644. #endif
  3645. }    /* IssueRevertCommand */
  3646.  
  3647. /*
  3648.     Name : IssueQuitCommand
  3649.     Purpose : Sends self a Quit AppleEvent
  3650. */
  3651. pascal OSErr IssueQuitCommand(void)
  3652. {
  3653. #ifndef RUNTIME
  3654.     AppleEvent    myAppleEvent;
  3655.     AppleEvent    defReply;
  3656.     OSErr         myErr;
  3657.     OSErr         ignoreErr;
  3658.     AEAddressDesc selfAddr;
  3659.     DescType      mySaveOpt;
  3660.  
  3661.     myAppleEvent.dataHandle = nil;
  3662.     selfAddr.dataHandle     = nil;
  3663.  
  3664.     myErr = MakeSelfAddress(&selfAddr);
  3665.  
  3666.     /*
  3667.         Build event
  3668.     */
  3669.     if (myErr == noErr)
  3670.         myErr  =
  3671.             AECreateAppleEvent(
  3672.                 kCoreEventClass,
  3673.                 kAEQuitApplication,
  3674.                 &selfAddr,
  3675.                 kAutoGenerateReturnID,
  3676.                 kAnyTransactionID,
  3677.                 &myAppleEvent);
  3678.     /*
  3679.         say which save option
  3680.     */
  3681.     mySaveOpt = kAEAsk;
  3682.  
  3683.     if (myErr == noErr)
  3684.         myErr =
  3685.             AEPutParamPtr(
  3686.                 &myAppleEvent,
  3687.                 keyAESaveOptions,
  3688.                 typeEnumerated,
  3689.                 (Ptr)&mySaveOpt,
  3690.                 sizeof(mySaveOpt));
  3691.     /*
  3692.         send the event
  3693.     */
  3694.     if (myErr==noErr)
  3695.         myErr =
  3696.             AESend(
  3697.                 &myAppleEvent,
  3698.                 &defReply,
  3699.                 kAENoReply+kAEAlwaysInteract,
  3700.                 kAENormalPriority,
  3701.                 kAEDefaultTimeout,
  3702.                 nil,
  3703.                 nil);
  3704.  
  3705.     if (myAppleEvent.dataHandle)
  3706.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3707.  
  3708.     if (selfAddr.dataHandle)
  3709.         ignoreErr = AEDisposeDesc(&selfAddr);
  3710.  
  3711.     return myErr;
  3712. #else
  3713.     DoQuit(kAEAsk);
  3714.     
  3715.     return noErr;
  3716. #endif
  3717. }    /* IssueQuitCommand */
  3718.  
  3719. #ifndef RUNTIME
  3720.  
  3721. /*
  3722.      Name :IssueCreatePublisher
  3723.      Purpose :Interact with user to get Publisher info
  3724.                         and the IssueAECommand to Publish currect selection
  3725. */
  3726. pascal void IssueCreatePublisher(DPtr whichDoc)
  3727. {
  3728.     AEAddressDesc selfAddr;
  3729.     AEDesc        selTextObj;
  3730.     OSErr         err;
  3731.     OSErr         ignoreErr;
  3732.     AppleEvent    publishCommandEvent;
  3733.     AppleEvent    ignoreReply;
  3734.  
  3735.       publishCommandEvent.dataHandle = nil;
  3736.     selfAddr.dataHandle = nil;
  3737.     selTextObj.dataHandle = nil;
  3738.  
  3739.     err = MakeSelfAddress(&selfAddr);
  3740.  
  3741.     if (err==noErr)
  3742.         err = MakeSelectedTextObj(whichDoc->theWindow, whichDoc->theText, &selTextObj);
  3743.  
  3744.     err =
  3745.         AECreateAppleEvent(
  3746.             kAEMiscStandards,
  3747.             kAECreatePublisher,
  3748.             &selfAddr,
  3749.             0,
  3750.             0,
  3751.             &publishCommandEvent) ;
  3752.  
  3753.     /*
  3754.         add parameter - the text to publish
  3755.     */
  3756.     if (err==noErr)
  3757.         err = AEPutParamDesc(&publishCommandEvent, keyDirectObject, &selTextObj);
  3758.  
  3759.     if (err==noErr)
  3760.         err =
  3761.             AESend(
  3762.                 &publishCommandEvent,
  3763.                 &ignoreReply,
  3764.                 kAENoReply+kAEAlwaysInteract,
  3765.                 kAEHighPriority,
  3766.                 10000,
  3767.                 nil,
  3768.                 nil);
  3769.  
  3770.       if (publishCommandEvent.dataHandle)
  3771.         ignoreErr = AEDisposeDesc(&publishCommandEvent);
  3772.  
  3773.     if (selTextObj.dataHandle)
  3774.         ignoreErr = AEDisposeDesc(&selTextObj);
  3775.  
  3776.     if (selfAddr.dataHandle)
  3777.         ignoreErr = AEDisposeDesc(&selfAddr);
  3778. } /*IssueCreatePublisher*/
  3779.  
  3780. #endif
  3781.  
  3782. #define kOK 1
  3783. #define kCancel 2
  3784. #define kOtherSize 4
  3785. #define kOutlineItem 5
  3786.  
  3787. pascal Boolean PoseSizeDialog(long *whatSize)
  3788. {
  3789.     GrafPtr   savedPort;
  3790.     DialogPtr aDialog;
  3791.     Str255    aString;
  3792.     short     itemHit;
  3793.  
  3794.     GetPort(&savedPort);
  3795.     aDialog = GetNewDialog(1004, nil, (WindowPtr)-1);
  3796.     DoShowWindow(aDialog);
  3797.     SetPort(aDialog);
  3798.  
  3799.     AdornDefaultButton(aDialog, kOutlineItem);
  3800.  
  3801.     /*set the edittext button to contain the right size*/
  3802.     NumToString(*whatSize, aString);
  3803.     SetText(aDialog, kOtherSize, aString);
  3804.  
  3805.     do {
  3806.         ModalDialog(nil, &itemHit);
  3807.     } while ((itemHit!=kOK) && (itemHit!=kCancel));
  3808.  
  3809.     if (itemHit == kOK)
  3810.         RetrieveText(aDialog, kOtherSize, aString);
  3811.  
  3812.     DisposDialog(aDialog);
  3813.     SetPort(savedPort);
  3814.  
  3815.     if (itemHit == kOK) {
  3816.         /*set the new size of the text*/
  3817.         StringToNum(aString, whatSize);
  3818.         if ((*whatSize<1) || (*whatSize>2000))
  3819.              *whatSize = 12;
  3820.     }
  3821.     return itemHit == kOK;
  3822. }
  3823.  
  3824. pascal void IssueFormatCommand(DPtr theDocument)
  3825. {
  3826.     Str255            name;
  3827. #ifndef RUNTIME
  3828.     AEDesc            desc;
  3829.     AEAddressDesc     theAddress;
  3830.     AEDesc            windowObj;
  3831. #endif
  3832.     OSErr             err;
  3833.     DocFormat        fmt;
  3834.     Boolean            defaultFormat;
  3835.     
  3836.     if (theDocument) {
  3837.         fmt.font         =     (*theDocument->theText)->txFont;
  3838.         fmt.size         =     (*theDocument->theText)->txSize;
  3839.         defaultFormat    =    false;
  3840.     } else {
  3841.         fmt                 =     gFormat;
  3842.         defaultFormat    =    true;
  3843.     }
  3844.     
  3845.     if (DoFormatDialog(&fmt, &defaultFormat)) {
  3846.         if (theDocument) {
  3847. #ifndef RUNTIME
  3848.             err = MakeSelfAddress(&theAddress);
  3849.             err = MakeWindowObj(theDocument->theWindow, &windowObj);
  3850.  
  3851.             if (err==noErr)
  3852.                   err = CreateOffsetDescriptor(fmt.size, &desc);
  3853.  
  3854.             if (err==noErr)
  3855.                 err = SendAESetObjProp(&windowObj, pPointSize, &desc, &theAddress);
  3856.                 
  3857.             err = MakeSelfAddress(&theAddress);
  3858.             err = MakeWindowObj(theDocument->theWindow, &windowObj);
  3859.         
  3860.             GetFontName(fmt.font, name);
  3861.         
  3862.             if (err==noErr)
  3863.                 err  = AECreateDesc(typeChar, (Ptr)&name[1], name[0], &desc);
  3864.         
  3865.             if (err==noErr)
  3866.                 err  = SendAESetObjProp(&windowObj, pFont, &desc, &theAddress);
  3867. #else
  3868.             (*theDocument->theText)->txFont = fmt.font;
  3869.             (*theDocument->theText)->txSize = fmt.size;
  3870.             RecalcFontInfo(theDocument->theText);
  3871.             AdjustScrollbars(theDocument, false);
  3872.             DrawPageExtras(theDocument);
  3873.             
  3874.             if (theDocument->kind == kDocumentWindow)
  3875.                 theDocument->dirty = true;
  3876. #endif
  3877.         }
  3878.         
  3879.         if (defaultFormat) {
  3880.             gFormat = fmt;
  3881.  
  3882.             if (gPrefsFile) {
  3883.                 short        resFile;
  3884.                 short    **    defaultFont;
  3885.             
  3886.                 resFile = CurResFile();
  3887.                 UseResFile(gPrefsFile);
  3888.                 
  3889.                 defaultFont = (short **) Get1Resource('PFNT', 128);
  3890.                 **defaultFont = gFormat.size;
  3891.                 GetFontName(gFormat.font, name);
  3892.                 SetResInfo((Handle) defaultFont, 128, name);
  3893.                 ChangedResource((Handle) defaultFont);
  3894.                 WriteResource((Handle) defaultFont);
  3895.                 UpdateResFile(gPrefsFile);
  3896.             
  3897.                 UseResFile(resFile);
  3898.             }
  3899.         }
  3900.     }
  3901. } /*IssueFormatCommand*/
  3902.  
  3903. #ifndef RUNTIME
  3904.  
  3905. pascal OSErr IssueSetDataObjToBufferContents(const AEDesc * theObj)
  3906. {
  3907.       OSErr             myErr;
  3908.     OSErr                ignoreErr;
  3909.     AEAddressDesc     theAddress;
  3910.     AppleEvent        myAppleEvent;
  3911.     AppleEvent        defReply;
  3912.  
  3913.     myErr = MakeSelfAddress(&theAddress);
  3914.  
  3915.     /* create event */
  3916.  
  3917.     if (myErr==noErr)
  3918.         myErr = AECreateAppleEvent(kAECoreSuite, kAESetData, &theAddress, 0, 0, &myAppleEvent);
  3919.  
  3920.     /* add prop obj spec to the event */
  3921.  
  3922.     if (myErr==noErr)
  3923.         myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, theObj);
  3924.  
  3925.     /* add prop data to the event */
  3926.  
  3927.     if (myErr==noErr)
  3928.         myErr =
  3929.             AEPutParamPtr(
  3930.                 &myAppleEvent,
  3931.                 keyAEData,
  3932.                 typeChar,
  3933.                 (Ptr)gTypingBuffer,
  3934.                 gCharsInBuffer);
  3935.  
  3936.     /* send event */
  3937.  
  3938.     if (myErr==noErr)
  3939.      if (gRecordingImplemented)
  3940.          myErr =
  3941.              AESend(
  3942.                 &myAppleEvent,
  3943.                 &defReply,
  3944.                 kAENoReply+kAEDontExecute,
  3945.                 kAENormalPriority,
  3946.                 kAEDefaultTimeout,
  3947.                 nil,
  3948.                 nil);
  3949.  
  3950.     if (theAddress.dataHandle)
  3951.         ignoreErr = AEDisposeDesc(&theAddress);
  3952.  
  3953.     if (myAppleEvent.dataHandle)
  3954.         ignoreErr = AEDisposeDesc(&myAppleEvent);
  3955.  
  3956.     return myErr;
  3957. }
  3958.  
  3959. pascal void AddKeyToTypingBuffer(DPtr theDocument, char theKey)
  3960. {
  3961.     OSErr myErr;
  3962.     OSErr ignoreErr;
  3963.  
  3964.     if (theKey==BS || theKey==FS || theKey==GS || theKey==RS || theKey==US) {
  3965.         FlushAndRecordTypingBuffer();
  3966.         if (theKey==BS) {
  3967.             if ((**theDocument->theText).selStart!=(**theDocument->theText).selEnd) {
  3968.                 myErr =
  3969.                     MakeTextObj(
  3970.                         theDocument->theWindow,
  3971.                         (**theDocument->theText).selStart,
  3972.                         (**theDocument->theText).selEnd,
  3973.                         &gTypingTargetObject);
  3974.             } else {
  3975.                 myErr =
  3976.                     MakeTextObj(
  3977.                         theDocument->theWindow,
  3978.                         (**theDocument->theText).selStart-1,
  3979.                         (**theDocument->theText).selStart,
  3980.                         &gTypingTargetObject);
  3981.             }
  3982.  
  3983.              myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject);
  3984.  
  3985.             ignoreErr = AEDisposeDesc(&gTypingTargetObject);
  3986.  
  3987.             gTypingTargetObject.dataHandle = nil;
  3988.         }
  3989.     } else {
  3990.         if (gCharsInBuffer==0)
  3991.             myErr =
  3992.                 MakeSelectedTextObj(
  3993.                     theDocument->theWindow,
  3994.                     theDocument->theText,
  3995.                     &gTypingTargetObject);
  3996.  
  3997.         gTypingBuffer[gCharsInBuffer++] = theKey;
  3998.     }
  3999. }
  4000.  
  4001. pascal void FlushAndRecordTypingBuffer(void)
  4002. {
  4003.       OSErr  myErr;
  4004.     OSErr  ignoreErr;
  4005.  
  4006.     if (gCharsInBuffer != 0) {
  4007.         myErr = IssueSetDataObjToBufferContents(&gTypingTargetObject);
  4008.  
  4009.         if (gTypingTargetObject.dataHandle)
  4010.             ignoreErr = AEDisposeDesc(&gTypingTargetObject);
  4011.     }
  4012.  
  4013.     gCharsInBuffer = 0;
  4014.     gTypingTargetObject.dataHandle = 0;
  4015. }
  4016.  
  4017. /*****************************************************************************/
  4018. /*
  4019.     Object Accessors
  4020. */
  4021.  
  4022. pascal OSErr WindowFromNullAccessor(
  4023.     DescType      wantClass,
  4024.     const AEDesc  *container,
  4025.     DescType      containerClass,
  4026.     DescType      form,
  4027.     const AEDesc  *selectionData,
  4028.     AEDesc        *value,
  4029.     long          theRefCon)
  4030. {
  4031. #pragma unused (container,theRefCon)
  4032.  
  4033.     OSErr       myErr;
  4034.     Str255      nameStr;
  4035.     WindowToken theWindow;
  4036.     short       index;
  4037.     AEDesc      resultDesc;
  4038.  
  4039.     myErr = errAEBadKeyForm;    /* or whatever */
  4040.  
  4041.     value->dataHandle     = nil;
  4042.     resultDesc.dataHandle = nil;
  4043.  
  4044.     /*
  4045.         should only be called with wantClass = cWindow and
  4046.         with containerClass = typeNull or typeMyAppl.
  4047.         Currently accept as either formName or formAbsolutePosition
  4048.     */
  4049.  
  4050.     if (
  4051.         (wantClass != cWindow) ||
  4052.         ((containerClass != typeNull) && (containerClass != typeMyAppl)) ||
  4053.         !((form == formName) || (form == formAbsolutePosition))
  4054.     )
  4055.         return errAEWrongDataType;
  4056.  
  4057.     if (form == formName) {
  4058.         myErr     = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  4059.         theWindow = WindowNameToWindowPtr(nameStr);
  4060.     }
  4061.  
  4062.     if (form == formAbsolutePosition) {
  4063.         myErr         = GetIntegerFromDescriptor(selectionData, &index);
  4064.  
  4065.         if (index<0)
  4066.             index = CountWindows()+index+1;
  4067.  
  4068.         theWindow = GetWindowPtrOfNthWindow(index);
  4069.     }
  4070.  
  4071.     if (myErr == noErr)
  4072.         myErr = AECreateDesc(typeMyWndw, (Ptr)&theWindow, sizeof(theWindow), value);
  4073.  
  4074.     return myErr;
  4075. }    /* WindowFromNullAccessor */
  4076.  
  4077. pascal OSErr ApplicationFromNullAccessor(
  4078.     DescType      wantClass,
  4079.     const AEDesc  *container,
  4080.     DescType      containerClass,
  4081.     DescType      form,
  4082.     const AEDesc  *selectionData,
  4083.     AEDesc        *value,
  4084.     long          theRefCon)
  4085. {
  4086. #pragma unused (container,selectionData,theRefCon)
  4087.  
  4088.     OSErr    myErr;
  4089.     appToken theApp;
  4090.     AEDesc   resultDesc;
  4091.  
  4092.     value->dataHandle     = nil;
  4093.     resultDesc.dataHandle = nil;
  4094.  
  4095.     /*
  4096.         should only be called with wantClass = cWindow and
  4097.         with containerClass = typeNull.
  4098.         Currently accept as either formName or formAbsolutePosition
  4099.     */
  4100.  
  4101.     if (
  4102.         (wantClass != cApplication) ||
  4103.         (containerClass != typeNull) ||
  4104.         !((form == formName) || (form == formAbsolutePosition))
  4105.     )
  4106.         return errAEWrongDataType;
  4107.  
  4108.     if ((form == formName) || (form == formAbsolutePosition)) {
  4109.         theApp.highLongOfPSN = 0;
  4110.         theApp.lowLongOfPSN  = kCurrentProcess;
  4111.     }
  4112.  
  4113.     myErr = AECreateDesc(typeMyAppl, (Ptr)&theApp, sizeof(theApp), value);
  4114.  
  4115.     return myErr;
  4116. }    /* ApplicationFromNullAccessor */
  4117.  
  4118. pascal void MoveToNonSpace(short *start, short limit, charsHandle myChars)
  4119. /*
  4120.     Treats space,comma, full stop, ; and : as space chars
  4121. */
  4122. {
  4123.     while (*start<=limit)
  4124.           switch ((**myChars)[*start]) {
  4125.           case ' ':
  4126.         case ',':
  4127.         case '.':
  4128.         case ':':
  4129.         case 10:
  4130.         case 13:
  4131.             (*start) +=1;
  4132.             break;
  4133.         default:
  4134.             return;
  4135.         }
  4136. }
  4137.  
  4138. pascal void MoveToSpace(short *start, short limit, charsHandle myChars)
  4139.     /*
  4140.         Treats space,comma, full stop, ; and : as space chars
  4141.     */
  4142. {
  4143.     while (*start<=limit)
  4144.           switch ((**myChars)[*start]) {
  4145.           case ' ':
  4146.         case ',':
  4147.         case '.':
  4148.         case ':':
  4149.         case 10:
  4150.         case 13:
  4151.             return;
  4152.         default:
  4153.             (*start) +=1;
  4154.             break;
  4155.         }
  4156. }
  4157.  
  4158. pascal short CountWords(TEHandle inTextHandle, short startAt, short forHowManyChars)
  4159. {
  4160.     charsHandle myChars;
  4161.     short       start;
  4162.     short       limit;
  4163.     short       myWords;
  4164.  
  4165.     myChars  = (charsHandle)(**inTextHandle).hText;
  4166.     limit    = startAt+forHowManyChars-1;
  4167.     start    = startAt;
  4168.     myWords  = 0;
  4169.     MoveToNonSpace(&start, limit, myChars);
  4170.     while (start<=limit) {
  4171.         myWords++;
  4172.         MoveToSpace(&start, limit, myChars);
  4173.         MoveToNonSpace(&start, limit, myChars);
  4174.     }
  4175.     return myWords;
  4176. } /* CountWords */
  4177.  
  4178. pascal void GetNthWordInfo(
  4179.     short    whichWord,
  4180.     TEHandle inTextHandle,
  4181.     short    *wordStartChar,
  4182.     short    *wordLength)
  4183.     /*
  4184.         On entry:    wordStartChar is start of char range to count in
  4185.                             wordLength is number of chars to consider
  4186.  
  4187.         On Exit : wordStartChar is start of requested word
  4188.                             wordLength is number of chars in word
  4189.     */
  4190. {
  4191.     charsHandle myChars;
  4192.     short       start;
  4193.     short       limit;
  4194.  
  4195.     myChars  = (charsHandle)(**inTextHandle).hText;
  4196.     limit    = *wordStartChar + *wordLength-1;
  4197.     start    = *wordStartChar;
  4198.     MoveToNonSpace(&start, limit, myChars);
  4199.     while ((start<=limit) && (whichWord>0)) {
  4200.  
  4201.         whichWord       = whichWord-1;
  4202.         *wordStartChar  = start;
  4203.         MoveToSpace(&start, limit, myChars);
  4204.         *wordLength     = start- *wordStartChar;
  4205.  
  4206.         MoveToNonSpace(&start, limit, myChars);
  4207.     }
  4208. } /* GetNthWordInfo */
  4209.  
  4210. pascal void GetWordInfo(
  4211.     short    whichWord,
  4212.     TEHandle inTextHandle,
  4213.     short    *wordStartChar,
  4214.     short    *wordLength)
  4215.     /*
  4216.         On wordStartChar entry is start of char range to count in
  4217.                             wordLength is number of chars to consider
  4218.  
  4219.         On Exit : wordStartChar is start of requested word
  4220.                             wordLength is number of chars in word
  4221.     */
  4222. {
  4223.     short noOfWords;
  4224.  
  4225.     noOfWords = CountWords(inTextHandle, *wordStartChar, *wordLength);
  4226.  
  4227.     if (whichWord<0)
  4228.         whichWord = noOfWords + whichWord + 1;
  4229.  
  4230.     if (whichWord>noOfWords) {
  4231.         *wordStartChar = *wordStartChar+*wordLength;
  4232.         *wordLength    = 0;
  4233.     } else
  4234.         GetNthWordInfo(whichWord, inTextHandle, wordStartChar, wordLength);
  4235. }
  4236.  
  4237. pascal short CountLines(TEHandle inTextHandle)
  4238. {
  4239.     /*
  4240.         CountLines makes use of info in TERec
  4241.     */
  4242.     return (**inTextHandle).nLines;
  4243. }
  4244.  
  4245. pascal short LineOfOffset(TEHandle theHTE, short charOffset)
  4246. {
  4247.     short n;
  4248.  
  4249.     n = (**theHTE).nLines;
  4250.  
  4251.     while (((**theHTE).lineStarts[n-1]>charOffset) &&
  4252.                  (n>0))
  4253.          n--;
  4254.  
  4255.     return n;
  4256. } /* LineOfOffset */
  4257.  
  4258. pascal void GetLineInfo(
  4259.     short    whichLine,
  4260.     TEHandle inTextHandle,
  4261.     short    *lineStartChar,
  4262.     short    *lineLength)
  4263. {
  4264.     short       noOfLines;
  4265.     charsHandle myChars;
  4266.  
  4267.     /* Addition of lines within text object */
  4268.     short       lineOfStart;
  4269.     short       lineOfEnd;
  4270.  
  4271.     lineOfStart = LineOfOffset(inTextHandle, *lineStartChar);
  4272.     lineOfEnd   = LineOfOffset(inTextHandle, *lineStartChar+*lineLength-1);
  4273.  
  4274.     myChars   = (charsHandle)(**inTextHandle).hText;
  4275.     noOfLines = lineOfEnd - lineOfStart + 1;
  4276.  
  4277.     if (whichLine<0)
  4278.         whichLine = noOfLines + whichLine + 1;
  4279.  
  4280.     noOfLines = CountLines(inTextHandle);
  4281.     whichLine = whichLine + lineOfStart - 1; /* convert offset relative to offset absolute */
  4282.  
  4283.     /* End of addition */
  4284.  
  4285.     if (whichLine<=lineOfEnd) {
  4286.         *lineStartChar = (**inTextHandle).lineStarts[whichLine-1];
  4287.         if (whichLine==noOfLines)
  4288.             *lineLength  = (**inTextHandle).teLength;
  4289.         else
  4290.             *lineLength  = (**inTextHandle).lineStarts[whichLine];
  4291.         *lineLength    = *lineLength-*lineStartChar;
  4292.         /*
  4293.             Don't return CR
  4294.         */
  4295.         if ((**myChars)[ *lineStartChar+*lineLength-1] == 13)
  4296.             *lineLength = *lineLength-1;
  4297.     } else {
  4298.         if (whichLine<noOfLines)
  4299.           *lineStartChar = (**inTextHandle).lineStarts[whichLine]; /* start of whichLine++ */
  4300.         else
  4301.             *lineStartChar = (**inTextHandle).teLength;
  4302.         *lineLength    = 0;
  4303.     }
  4304. } /* GetLineInfo */
  4305.  
  4306. pascal OSErr TextElemFromWndwAccessor(
  4307.     DescType     wantClass,
  4308.     const AEDesc *container,
  4309.     DescType     containerClass,
  4310.     DescType     form,
  4311.     const AEDesc *selectionData,
  4312.     AEDesc       *value,
  4313.     long         theRefCon)
  4314. {
  4315. #pragma unused (theRefCon)
  4316.  
  4317.     OSErr       myErr;
  4318.     OSErr       ignoreErr;
  4319.     WindowToken theWindow;
  4320.     Size        actSize;
  4321.     long        index;
  4322.     TextToken   theTextToken;
  4323.     AERecord    selectionRecord;
  4324.     TextToken   startText;
  4325.     TextToken   stopText;
  4326.     DescType    returnedType;
  4327.     AEDesc      windDesc;
  4328.     TEHandle    theHTE;
  4329.     DPtr        theDocument;
  4330.     short       wordStartChar;
  4331.     short       wordLength;
  4332.  
  4333.     myErr = -1700;    /* or whatever */
  4334.  
  4335.     selectionRecord.dataHandle = nil;
  4336.  
  4337.     /* do some checking for robustness' sake */
  4338.  
  4339.     if (
  4340.         (containerClass != cWindow) ||
  4341.         ((wantClass != cText) && (wantClass != cChar) && (wantClass != cSpot) && (wantClass != cWord) && (wantClass != cLine)    ) ||
  4342.         ((form!=formRange) && (form!=formAbsolutePosition))
  4343.     )
  4344.         return errAEWrongDataType;
  4345.  
  4346.     /* let's get the window which contains the text element */
  4347.  
  4348.     myErr = AECoerceDesc(container, typeMyWndw, &windDesc);
  4349.     GetRawDataFromDescriptor(&windDesc, (Ptr)&theWindow, sizeof(theWindow), &actSize);
  4350.     myErr = AEDisposeDesc(&windDesc);
  4351.  
  4352.     if (theWindow==nil)
  4353.         myErr = errAEIllegalIndex;
  4354.     else {
  4355.         theTextToken.tokenWindow = theWindow;
  4356.  
  4357.         theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  4358.         theHTE      = theDocument->theText;
  4359.  
  4360.         switch (form) {
  4361.         case formAbsolutePosition:
  4362.             myErr = GetLongIntFromDescriptor(selectionData, &index);
  4363.  
  4364.             switch (wantClass) {
  4365.             case cSpot:
  4366.                 if (index<0)
  4367.                     theTextToken.tokenOffset = (**theHTE).teLength+index+2; /* Past last char */
  4368.                 else
  4369.                     theTextToken.tokenOffset = index;
  4370.  
  4371.                 theTextToken.tokenLength = 0;
  4372.                 break;
  4373.  
  4374.             case cChar:
  4375.                 if (index<0)
  4376.                     theTextToken.tokenOffset = (**theHTE).teLength+index+1;
  4377.                 else
  4378.                   theTextToken.tokenOffset = index;
  4379.  
  4380.                 theTextToken.tokenLength = 1;
  4381.                 break;
  4382.  
  4383.             case cWord:
  4384.                 wordStartChar = 0;
  4385.                 wordLength    = (**theHTE).teLength;
  4386.                 GetWordInfo(index, theHTE, &wordStartChar, &wordLength); /* zero based */
  4387.                 theTextToken.tokenOffset = wordStartChar+1;
  4388.                 theTextToken.tokenLength = wordLength;
  4389.                 break;
  4390.  
  4391.             case cLine:
  4392.                 wordStartChar = 0;
  4393.                 wordLength    = (**theHTE).teLength;
  4394.                 GetLineInfo(index, theHTE, &wordStartChar, &wordLength); /* zero based */
  4395.                 theTextToken.tokenOffset = wordStartChar+1;
  4396.                 theTextToken.tokenLength = wordLength;
  4397.                 break;
  4398.             
  4399.             case cText:
  4400.                 theTextToken.tokenOffset = 1;
  4401.                 theTextToken.tokenLength = (**theHTE).teLength;
  4402.                 myErr                             = noErr;
  4403.                 break;
  4404.             }
  4405.             break;
  4406.  
  4407.         case formRange:
  4408.             /* coerce the selection data into an AERecord */
  4409.  
  4410.              myErr = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
  4411.  
  4412.             /* get the start object as a text token -
  4413.                     this will reenter this proc but as formAbsolutePosition via the coercion handler*/
  4414.  
  4415.             myErr =
  4416.                 AEGetKeyPtr(
  4417.                     &selectionRecord,
  4418.                     keyAERangeStart,
  4419.                     typeMyText,
  4420.                     &returnedType,
  4421.                     (Ptr)&startText,
  4422.                     sizeof(startText),
  4423.                     &actSize);
  4424.  
  4425.             /* now do the same for the stop object */
  4426.             if (myErr==noErr)
  4427.                 myErr =
  4428.                     AEGetKeyPtr(
  4429.                         &selectionRecord,
  4430.                         keyAERangeStop,
  4431.                         typeMyText,
  4432.                         &returnedType,
  4433.                         (Ptr)&stopText,
  4434.                         sizeof(stopText),
  4435.                         &actSize);
  4436.  
  4437.             if (myErr==noErr)
  4438.                 if (
  4439.                     (theTextToken.tokenWindow != stopText.tokenWindow) ||
  4440.                     (theTextToken.tokenWindow != startText.tokenWindow)
  4441.                 )
  4442.                     myErr = errAECorruptData;    /* or whatever ????*/
  4443.  
  4444.             theTextToken.tokenOffset  = startText.tokenOffset;
  4445.             theTextToken.tokenLength  = stopText.tokenOffset + stopText.tokenLength - startText.tokenOffset;
  4446.  
  4447.             if (theTextToken.tokenLength<0)
  4448.                 myErr = errAECorruptData;    /* or whatever */
  4449.  
  4450.             ignoreErr = AEDisposeDesc(&selectionRecord);
  4451.  
  4452.             break;
  4453.         }
  4454.     }
  4455.  
  4456.     /* return theTextToken in a descriptor */
  4457.  
  4458.     if (myErr==noErr)
  4459.         myErr = AECreateDesc(typeMyText, (Ptr)&theTextToken, sizeof(theTextToken), value);
  4460.  
  4461.     return myErr;
  4462. }    /* TextElemFromWndwAccessor */
  4463.  
  4464. pascal OSErr TextElemFromTextAccessor(
  4465.     DescType     wantClass,
  4466.     const AEDesc *container,
  4467.     DescType     containerClass,
  4468.     DescType     form,
  4469.     const AEDesc *selectionData,
  4470.     AEDesc       *value,
  4471.     long         theRefCon)
  4472. {
  4473. #pragma unused (theRefCon, containerClass)
  4474.  
  4475.     OSErr       myErr;
  4476.     Size        actSize;
  4477.     long        index;
  4478.     TextToken   theTextToken;
  4479.     AERecord    selectionRecord;
  4480.     TextToken   startText;
  4481.     TextToken   stopText;
  4482.     DescType    returnedType;
  4483.     AEDesc      textDesc;
  4484.     TEHandle    theHTE;
  4485.     short       wordStartChar;
  4486.     short       wordLength;
  4487.     DPtr        theDocument;
  4488.  
  4489.     myErr = -1700;    /* or whatever */
  4490.  
  4491.     /* do some checking for robustness' sake */
  4492.  
  4493.     if (
  4494.         ((wantClass != cText) && (wantClass != cChar) && (wantClass != cSpot) && (wantClass != cLine) && (wantClass != cWord)) ||
  4495.         ((form != formAbsolutePosition) && (form != formRange))
  4496.     )
  4497.         return errAEWrongDataType;
  4498.  
  4499.     /* let's get the src text */
  4500.  
  4501.     myErr = AECoerceDesc(container, typeMyText, &textDesc);
  4502.     GetRawDataFromDescriptor(&textDesc, (Ptr)&theTextToken, sizeof(theTextToken), &actSize);
  4503.  
  4504.     myErr = AEDisposeDesc(&textDesc);
  4505.  
  4506.     theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  4507.     theHTE      = theDocument->theText;
  4508.  
  4509.     switch (form) {
  4510.     case formAbsolutePosition:
  4511.         myErr = GetLongIntFromDescriptor(selectionData, &index);
  4512.  
  4513.         switch (wantClass) {
  4514.         case cSpot:
  4515.             if (index<0)
  4516.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4517.             else
  4518.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4519.             theTextToken.tokenLength = 0;
  4520.             break;
  4521.  
  4522.         case cChar:
  4523.             if (index<0)
  4524.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index+1+theTextToken.tokenLength;
  4525.             else
  4526.                 theTextToken.tokenOffset = theTextToken.tokenOffset+index-1;
  4527.             theTextToken.tokenLength = 1;
  4528.             break;
  4529.  
  4530.         case cWord:
  4531.             wordStartChar = theTextToken.tokenOffset-1;
  4532.             wordLength    = theTextToken.tokenLength;
  4533.  
  4534.             GetWordInfo(index, theHTE, &wordStartChar, &wordLength);/*zero based*/
  4535.  
  4536.             theTextToken.tokenOffset = wordStartChar+1;
  4537.             theTextToken.tokenLength = wordLength;
  4538.             break;
  4539.  
  4540.         case cLine:
  4541.             wordStartChar = theTextToken.tokenOffset-1;
  4542.             wordLength    = theTextToken.tokenLength;
  4543.  
  4544.             GetLineInfo(index, theHTE, &wordStartChar, &wordLength);
  4545.  
  4546.             theTextToken.tokenOffset = wordStartChar+1;
  4547.             theTextToken.tokenLength = wordLength;
  4548.             break;
  4549.         }
  4550.         break;
  4551.  
  4552.     case formRange:
  4553.         /* coerce the selection data into an AERecord */
  4554.  
  4555.          myErr = AECoerceDesc(selectionData, typeAERecord, &selectionRecord);
  4556.  
  4557.         /* get the start object as a text token -
  4558.                 this will reenter this proc but as formAbsolutePosition via the coercion handler*/
  4559.  
  4560.         myErr =
  4561.             AEGetKeyPtr(
  4562.                 &selectionRecord,
  4563.                 keyAERangeStart,
  4564.                 typeMyText,
  4565.                 &returnedType,
  4566.                 (Ptr)&startText,
  4567.                 sizeof(startText),
  4568.                 &actSize);
  4569.  
  4570.         /* now do the same for the stop object */
  4571.  
  4572.         if (myErr==noErr)
  4573.             myErr =
  4574.                 AEGetKeyPtr(
  4575.                     &selectionRecord,
  4576.                     keyAERangeStop,
  4577.                     typeMyText,
  4578.                     &returnedType,
  4579.                     (Ptr)&stopText,
  4580.                     sizeof(stopText),
  4581.                     &actSize);
  4582.  
  4583.         if (myErr==noErr)
  4584.             if ((theTextToken.tokenWindow != stopText.tokenWindow) ||
  4585.                   (theTextToken.tokenWindow != startText.tokenWindow))
  4586.                 myErr = errAECorruptData;    /* or whatever */
  4587.  
  4588.         theTextToken.tokenOffset  = startText.tokenOffset;
  4589.         theTextToken.tokenLength  = stopText.tokenOffset + stopText.tokenLength - startText.tokenOffset;
  4590.  
  4591.         myErr = AEDisposeDesc(&selectionRecord);
  4592.         break;
  4593.     }
  4594.  
  4595.     /* return theTextToken in a descriptor */
  4596.  
  4597.     myErr =
  4598.         AECreateDesc(
  4599.             typeMyText,
  4600.             (Ptr)&theTextToken,
  4601.             sizeof(theTextToken),
  4602.             value);
  4603.  
  4604.     return myErr;
  4605. }    /* TextElemFromTextAccessor */
  4606.  
  4607. pascal OSErr PropertyFromTextAccessor(
  4608.     DescType     wantClass,
  4609.     const AEDesc *container,
  4610.     DescType     containerClass,
  4611.     DescType     form,
  4612.     const AEDesc *selectionData,
  4613.     AEDesc       *value,
  4614.     long         theRefCon)
  4615. {
  4616. #pragma unused (theRefCon, containerClass)
  4617.  
  4618.     OSErr         myErr;
  4619.     OSErr         ignoreErr;
  4620.     TextToken     theTextToken;
  4621.     DescType      theProperty;
  4622.     AEDesc        textDesc;
  4623.     AEDesc        propDesc;
  4624.     Size          actualSize;
  4625.     textPropToken myTextProp;
  4626.  
  4627.     value->dataHandle   = nil;
  4628.     textDesc.dataHandle = nil;
  4629.     propDesc.dataHandle = nil;
  4630.  
  4631.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4632.         return errAEWrongDataType;
  4633.     }
  4634.  
  4635.     /* get the text token */
  4636.     myErr = AECoerceDesc(container, typeMyText, &textDesc);
  4637.     GetRawDataFromDescriptor(&textDesc, (Ptr)&theTextToken, sizeof(theTextToken), &actualSize);
  4638.  
  4639.     /* get the property */
  4640.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4641.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4642.  
  4643.     /*
  4644.         Combine the two into single token
  4645.     */
  4646.     myTextProp.propertyTextToken = theTextToken;
  4647.     myTextProp.propertyProperty  = theProperty;
  4648.  
  4649.     myErr = AECreateDesc(typeMyTextProp, (Ptr)&myTextProp, sizeof(myTextProp), value);
  4650.  
  4651.     if (textDesc.dataHandle)
  4652.         ignoreErr = AEDisposeDesc(&textDesc);
  4653.  
  4654.     if (propDesc.dataHandle)
  4655.         ignoreErr = AEDisposeDesc(&propDesc);
  4656.  
  4657.     return myErr;
  4658. }    /* PropertyFromTextAccessor */
  4659.  
  4660. pascal OSErr PropertyFromWndwAccessor(
  4661.     DescType     wantClass,
  4662.     const AEDesc *container,
  4663.     DescType     containerClass,
  4664.     DescType     form,
  4665.     const AEDesc *selectionData,
  4666.     AEDesc       *value,
  4667.     long         theRefCon)
  4668. {
  4669. #pragma unused (theRefCon, containerClass)
  4670.  
  4671.     OSErr           myErr;
  4672.     OSErr           ignoreErr;
  4673.     WindowToken     theWindowToken;
  4674.     DescType        theProperty;
  4675.     AEDesc          windowDesc;
  4676.     AEDesc          propDesc;
  4677.     Size            actualSize;
  4678.     windowPropToken myWindowProp;
  4679.  
  4680.     value->dataHandle     = nil;
  4681.     windowDesc.dataHandle = nil;
  4682.     propDesc.dataHandle   = nil;
  4683.  
  4684.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4685.         return errAEWrongDataType;
  4686.     }
  4687.  
  4688.     /* get the window token - it's the container */
  4689.     myErr = AECoerceDesc(container, typeMyWndw, &windowDesc);
  4690.     GetRawDataFromDescriptor(&windowDesc, (Ptr)&theWindowToken, sizeof(theWindowToken), &actualSize);
  4691.  
  4692.     /* Check the window exists */
  4693.     if (theWindowToken==nil)
  4694.         myErr = errAEIllegalIndex;
  4695.     else {
  4696.  
  4697.         /* get the property - it's in the selection data */
  4698.  
  4699.         myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4700.         GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4701.         /*
  4702.             Combine the two into single token
  4703.         */
  4704.         myWindowProp.tokenWindowToken = theWindowToken;
  4705.         myWindowProp.tokenProperty    = theProperty;
  4706.  
  4707.         myErr = AECreateDesc(typeMyWindowProp, (Ptr)&myWindowProp, sizeof(myWindowProp), value);
  4708.     }
  4709.  
  4710.     if (windowDesc.dataHandle)
  4711.         ignoreErr = AEDisposeDesc(&windowDesc);
  4712.  
  4713.     if (propDesc.dataHandle)
  4714.         ignoreErr = AEDisposeDesc(&propDesc);
  4715.  
  4716.     return myErr;
  4717. }    /* PropertyFromWndwAccessor */
  4718.  
  4719. pascal OSErr PropertyFromApplAccessor(
  4720.     DescType     wantClass,
  4721.     const AEDesc *container,
  4722.     DescType     containerClass,
  4723.     DescType     form,
  4724.     const AEDesc *selectionData,
  4725.     AEDesc       *value,
  4726.     long         theRefCon)
  4727. {
  4728. #pragma unused (theRefCon, containerClass)
  4729.  
  4730.     OSErr         myErr;
  4731.     OSErr         ignoreErr;
  4732.     appToken      theApplToken;
  4733.     DescType      theProperty;
  4734.     AEDesc        applDesc;
  4735.     AEDesc        propDesc;
  4736.     Size          actualSize;
  4737.     applPropToken myApplProp;
  4738.  
  4739.     value->dataHandle     = nil;
  4740.     applDesc.dataHandle   = nil;
  4741.     propDesc.dataHandle   = nil;
  4742.  
  4743.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4744.         return errAEWrongDataType;
  4745.     }
  4746.  
  4747.     /* get the application token - it's the container */
  4748.  
  4749.     myErr = AECoerceDesc(container, typeMyAppl, &applDesc);
  4750.     GetRawDataFromDescriptor(&applDesc, (Ptr)&theApplToken, sizeof(theApplToken), &actualSize);
  4751.  
  4752.     /* get the property - it's in the selection data */
  4753.  
  4754.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4755.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4756.     /*
  4757.         Combine the two into single token
  4758.     */
  4759.     myApplProp.tokenApplToken    = theApplToken;
  4760.     myApplProp.tokenApplProperty = theProperty;
  4761.  
  4762.     myErr = AECreateDesc(typeMyApplProp, (Ptr)&myApplProp, sizeof(myApplProp), value);
  4763.  
  4764.     if (applDesc.dataHandle)
  4765.         ignoreErr = AEDisposeDesc(&applDesc);
  4766.  
  4767.     if (propDesc.dataHandle)
  4768.         ignoreErr = AEDisposeDesc(&propDesc);
  4769.  
  4770.     return myErr;
  4771. }    /* PropertyFromApplAccessor */
  4772.  
  4773. pascal OSErr MenuNameToMenuToken(const Str255 theName, MenuToken *theToken)
  4774. {
  4775.     short   index;
  4776.  
  4777.     for (index=appleM; index<kLastMenu; index++) {
  4778.         if (IUEqualString(theName, (**(myMenus[index])).menuData)==0) {
  4779.             theToken->theTokenMenu = myMenus[index];
  4780.             theToken->theTokenID   = index+appleID;
  4781.             return noErr;
  4782.         }
  4783.     }
  4784.     return errAEIllegalIndex;
  4785. }
  4786.  
  4787. pascal OSErr MenuFromNullAccessor(
  4788.     DescType      wantClass,
  4789.     const AEDesc  *container,
  4790.     DescType      containerClass,
  4791.     DescType      form,
  4792.     const AEDesc  *selectionData,
  4793.     AEDesc        *value,
  4794.     long          theRefCon)
  4795. {
  4796. #pragma unused (container,theRefCon)
  4797.  
  4798.     OSErr       myErr;
  4799.     Str255      nameStr;
  4800.     MenuToken   theMenu;
  4801.     short       index;
  4802.     AEDesc      resultDesc;
  4803.  
  4804.     myErr = errAEBadKeyForm;    /* or whatever */
  4805.  
  4806.     value->dataHandle     = nil;
  4807.     resultDesc.dataHandle = nil;
  4808.  
  4809.     /*
  4810.         should only be called with wantClass = cMenu and
  4811.         with containerClass = typeNull or typeMyAppl.
  4812.         Currently accept as either formName or formAbsolutePosition
  4813.     */
  4814.  
  4815.     if (
  4816.         (wantClass != cMenu) ||
  4817.         ((containerClass != typeNull) && (containerClass != typeMyAppl)) ||
  4818.         !((form == formName) || (form == formAbsolutePosition))
  4819.     )
  4820.         return errAEWrongDataType;
  4821.  
  4822.     if (form == formName) {
  4823.         myErr = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  4824.         myErr = MenuNameToMenuToken(nameStr, &theMenu);
  4825.     }
  4826.  
  4827.     if (form == formAbsolutePosition) {
  4828.         myErr     = GetIntegerFromDescriptor(selectionData, &index);
  4829.         if (index<0)
  4830.             index = kLastMenu + index + 1;
  4831.  
  4832.         if (index>0 && index<kLastMenu+1) {
  4833.             theMenu.theTokenMenu = myMenus[index-1];
  4834.             theMenu.theTokenID   = index-1+appleID;
  4835.         } else
  4836.             myErr = errAEIllegalIndex;    /* or whatever */
  4837.     }
  4838.  
  4839.     if (myErr == noErr)
  4840.         myErr = AECreateDesc(typeMyMenu, (Ptr)&theMenu, sizeof(theMenu), value);
  4841.  
  4842.     return myErr;
  4843. }    /* MenuFromNullAccessor */
  4844.  
  4845. pascal OSErr PropertyFromMenuAccessor(
  4846.     DescType     wantClass,
  4847.     const AEDesc *container,
  4848.     DescType     containerClass,
  4849.     DescType     form,
  4850.     const AEDesc *selectionData,
  4851.     AEDesc       *value,
  4852.     long         theRefCon)
  4853. {
  4854. #pragma unused (theRefCon, containerClass)
  4855.  
  4856.     OSErr         myErr;
  4857.     OSErr         ignoreErr;
  4858.     MenuToken     theMenuToken;
  4859.     DescType      theProperty;
  4860.     AEDesc        menuDesc;
  4861.     AEDesc        propDesc;
  4862.     Size          actualSize;
  4863.     MenuPropToken myMenuProp;
  4864.  
  4865.     value->dataHandle     = nil;
  4866.     menuDesc.dataHandle   = nil;
  4867.     propDesc.dataHandle   = nil;
  4868.  
  4869.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4870.         return errAEWrongDataType;
  4871.     }
  4872.  
  4873.     /* get the menu token - it's the container */
  4874.  
  4875.     myErr = AECoerceDesc(container, typeMyMenu, &menuDesc);
  4876.     GetRawDataFromDescriptor(&menuDesc, (Ptr)&theMenuToken, sizeof(theMenuToken), &actualSize);
  4877.  
  4878.     /* get the property - it's in the selection data */
  4879.  
  4880.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4881.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4882.  
  4883.     /*
  4884.         Combine the two into single token
  4885.     */
  4886.     myMenuProp.theMenuToken = theMenuToken;
  4887.     myMenuProp.theMenuProp  = theProperty;
  4888.  
  4889.     myErr = AECreateDesc(typeMyMenuProp, (Ptr)&myMenuProp, sizeof(myMenuProp), value);
  4890.  
  4891.     if (menuDesc.dataHandle)
  4892.         ignoreErr = AEDisposeDesc(&menuDesc);
  4893.  
  4894.     if (propDesc.dataHandle)
  4895.         ignoreErr = AEDisposeDesc(&propDesc);
  4896.  
  4897.     return myErr;
  4898. }    /* PropertyFromMenuAccessor */
  4899.  
  4900. pascal OSErr PropertyFromMenuItemAccessor(
  4901.     DescType     wantClass,
  4902.     const AEDesc *container,
  4903.     DescType     containerClass,
  4904.     DescType     form,
  4905.     const AEDesc *selectionData,
  4906.     AEDesc       *value,
  4907.     long         theRefCon)
  4908. {
  4909. #pragma unused (theRefCon, containerClass)
  4910.  
  4911.     OSErr         myErr;
  4912.     OSErr         ignoreErr;
  4913.     MenuItemToken theMenuItemToken;
  4914.     DescType      theProperty;
  4915.     AEDesc        itemDesc;
  4916.     AEDesc        propDesc;
  4917.     Size          actualSize;
  4918.     MenuItemPropToken myItemProp;
  4919.  
  4920.     value->dataHandle     = nil;
  4921.     itemDesc.dataHandle   = nil;
  4922.     propDesc.dataHandle   = nil;
  4923.  
  4924.     if ((wantClass != cProperty) || (form != formPropertyID)) {
  4925.         return errAEWrongDataType;
  4926.     }
  4927.  
  4928.     /* get the menu token - it's the container */
  4929.  
  4930.     myErr = AECoerceDesc(container, typeMyMenuItem, &itemDesc);
  4931.     GetRawDataFromDescriptor(&itemDesc, (Ptr)&theMenuItemToken, sizeof(theMenuItemToken), &actualSize);
  4932.  
  4933.     /* get the property - it's in the selection data */
  4934.  
  4935.     myErr = AECoerceDesc(selectionData, typeType, &propDesc);
  4936.     GetRawDataFromDescriptor(&propDesc, (Ptr)&theProperty, sizeof(theProperty), &actualSize);
  4937.     /*
  4938.         Combine the two into single token
  4939.     */
  4940.     myItemProp.theItemToken  = theMenuItemToken;
  4941.     myItemProp.theItemProp   = theProperty;
  4942.  
  4943.     myErr = AECreateDesc(typeMyItemProp, (Ptr)&myItemProp, sizeof(myItemProp), value);
  4944.  
  4945.     if (itemDesc.dataHandle)
  4946.         ignoreErr = AEDisposeDesc(&itemDesc);
  4947.  
  4948.     if (propDesc.dataHandle)
  4949.         ignoreErr = AEDisposeDesc(&propDesc);
  4950.  
  4951.     return myErr;
  4952. }    /* PropertyFromMenuItemAccessor */
  4953.  
  4954. pascal OSErr ItemNameToItemIndex(const Str255 theName, MenuHandle theMenu, short *theIndex)
  4955. {
  4956.     short   index;
  4957.     short   maxItems;
  4958.     Str255  menuName;
  4959.  
  4960.     maxItems = CountMItems(theMenu);
  4961.  
  4962.     for (index=1; index<=maxItems; index++) {
  4963.         GetItem(theMenu, index, menuName);
  4964.         if (IUEqualString(theName, menuName)==0) {
  4965.             *theIndex = index;
  4966.             return noErr;
  4967.         }
  4968.     }
  4969.     return errAEIllegalIndex;
  4970. }
  4971.  
  4972. pascal OSErr MenuItemFromMenuAccessor(
  4973.     DescType     wantClass,
  4974.     const AEDesc *container,
  4975.     DescType     containerClass,
  4976.     DescType     form,
  4977.     const AEDesc *selectionData,
  4978.     AEDesc       *value,
  4979.     long         theRefCon)
  4980. {
  4981. #pragma unused (theRefCon)
  4982.  
  4983.     OSErr         myErr;
  4984.     OSErr         ignoreErr;
  4985.     MenuItemToken theMenuItemToken;
  4986.     MenuToken     theMenuToken;
  4987.     AEDesc        menuDesc;
  4988.     Size          actualSize;
  4989.     Str255        nameStr;
  4990.     short         maxItems;
  4991.     short         index;
  4992.  
  4993.     value->dataHandle     = nil;
  4994.     menuDesc.dataHandle   = nil;
  4995.  
  4996.     if (
  4997.         (wantClass != cMenuItem) || (containerClass != cMenu) ||
  4998.         ((form != formAbsolutePosition) && (form != formName))
  4999.     ) {
  5000.         return errAEWrongDataType;
  5001.     }
  5002.  
  5003.     /* get the menu token - it's the container */
  5004.  
  5005.     myErr = AECoerceDesc(container, typeMyMenu, &menuDesc);
  5006.     GetRawDataFromDescriptor(&menuDesc, (Ptr)&theMenuToken, sizeof(theMenuToken), &actualSize);
  5007.  
  5008.     if (form==formAbsolutePosition) {
  5009.         myErr = GetIntegerFromDescriptor(selectionData, &index);
  5010.         maxItems = CountMItems(theMenuToken.theTokenMenu);
  5011.  
  5012.         if (index<0)
  5013.             index = maxItems + index + 1;
  5014.  
  5015.         if ((index<1) || (index>maxItems))
  5016.           myErr = errAEIllegalIndex;
  5017.     }
  5018.  
  5019.     if (form == formName) {
  5020.         myErr  = GetPStringFromDescriptor(selectionData, (char *)nameStr);
  5021.         myErr  = ItemNameToItemIndex(nameStr, theMenuToken.theTokenMenu, &index);
  5022.     }
  5023.  
  5024.     /*
  5025.         Combine the two into single token
  5026.     */
  5027.  
  5028.     theMenuItemToken.theMenuToken  = theMenuToken;
  5029.     theMenuItemToken.theTokenItem  = index;
  5030.  
  5031.     if (myErr==noErr)
  5032.         myErr = AECreateDesc(typeMyMenuItem, (Ptr)&theMenuItemToken, sizeof(theMenuItemToken), value);
  5033.  
  5034.     if (menuDesc.dataHandle)
  5035.         ignoreErr = AEDisposeDesc(&menuDesc);
  5036.  
  5037.     return myErr;
  5038. }    /* MenuItemFromMenuAccessor */
  5039.  
  5040. /*******************************************************************************/
  5041. /*
  5042.     Stuff for counting objects
  5043. */
  5044.  
  5045. pascal OSErr MyCountProc(
  5046.     DescType     desiredType,
  5047.     DescType     containerClass,
  5048.     const AEDesc *container,
  5049.     long         *result)
  5050. /* so far all I count is:
  5051.   (1) the number of active windows in the app;
  5052.   (2) the number of words in a window
  5053. */
  5054. {
  5055.     OSErr       myErr;
  5056.     WindowToken theWindowToken;
  5057.     DPtr        theDocument;
  5058.     TEHandle    theHTE;
  5059.     AEDesc      newDesc;
  5060.     short       wordStart;
  5061.     short       wordLength;
  5062.     Size        tokenSize;
  5063.     TextToken   theTextToken;
  5064.  
  5065.     *result = -1;    /* easily recognized illegal value */
  5066.  
  5067.     myErr = errAEWrongDataType;
  5068.  
  5069.     if (desiredType == cWindow) {
  5070.         if ((containerClass == typeNull) || (containerClass == cApplication))
  5071.             *result = CountWindows();
  5072.     }
  5073.  
  5074.     if ((desiredType == cWord) || (desiredType == cLine) || (desiredType == cChar)) {
  5075.         myErr = AECoerceDesc(container, typeMyWndw, &newDesc);
  5076.         if (newDesc.descriptorType!=typeNull) {
  5077.                 GetRawDataFromDescriptor(
  5078.                     &newDesc,
  5079.                     (Ptr)&theWindowToken,
  5080.                     sizeof(theWindowToken),
  5081.                     &tokenSize);
  5082.  
  5083.                 myErr = AEDisposeDesc(&newDesc);
  5084.  
  5085.                 if (theWindowToken==nil)
  5086.                     myErr = errAEIllegalIndex;
  5087.                 else {
  5088.                     theDocument = DPtrFromWindowPtr(theWindowToken);
  5089.                     theHTE      = theDocument->theText;
  5090.  
  5091.                     if (desiredType == cWord) {
  5092.                         wordStart   = 0;
  5093.                         wordLength  = (**theHTE).teLength;
  5094.                         *result     = CountWords(theHTE, wordStart, wordLength);
  5095.                     }
  5096.  
  5097.                     if (desiredType == cChar)
  5098.                         *result = (**theHTE).teLength;
  5099.  
  5100.                     if (desiredType == cLine)
  5101.                         *result = CountLines(theHTE);
  5102.                 }
  5103.             }
  5104.  
  5105.         myErr = AECoerceDesc(container, typeMyText, &newDesc);
  5106.         if (newDesc.descriptorType!=typeNull) {
  5107.             GetRawDataFromDescriptor(
  5108.                 &newDesc,
  5109.                 (Ptr)&theTextToken,
  5110.                 sizeof(theTextToken),
  5111.                 &tokenSize);
  5112.  
  5113.             myErr = AEDisposeDesc(&newDesc);
  5114.  
  5115.             theDocument = DPtrFromWindowPtr(theTextToken.tokenWindow);
  5116.             theHTE      = theDocument->theText;
  5117.  
  5118.             if (desiredType == cWord) {
  5119.                 wordStart   = theTextToken.tokenOffset-1;
  5120.                 wordLength  = theTextToken.tokenLength;
  5121.                 *result     = CountWords(theHTE, wordStart, wordLength);
  5122.             }
  5123.  
  5124.             if (desiredType == cChar)
  5125.                 *result = theTextToken.tokenLength;
  5126.  
  5127.             if (desiredType == cLine)
  5128.                 *result    =
  5129.                     LineOfOffset(theHTE,theTextToken.tokenOffset-1) -
  5130.                     LineOfOffset(theHTE,theTextToken.tokenOffset+theTextToken.tokenLength-1)
  5131.                     +1;
  5132.         }
  5133.     }
  5134.  
  5135.     return myErr;
  5136. }    /* MyCountProc */
  5137.  
  5138. /*******************************************************************************/
  5139. /*
  5140.     Coercion Handlers - Allow AEResolve to do the hard work
  5141. */
  5142. pascal OSErr CoerceObjToAnything(
  5143.     const AEDesc *theAEDesc,
  5144.     DescType     toType,
  5145.     long         handlerRefCon,
  5146.     AEDesc       *result)
  5147. /*
  5148.     CoerceObjToAnything functions by using AEResolve to do the hard
  5149.     work.
  5150. */
  5151. {
  5152. #pragma unused (handlerRefCon)
  5153.  
  5154.     OSErr  myErr;
  5155.     AEDesc objDesc;
  5156.  
  5157.     myErr = errAECoercionFail;
  5158.  
  5159.     result->dataHandle = nil;
  5160.     objDesc.dataHandle = nil;
  5161.  
  5162.  
  5163.     if (theAEDesc->descriptorType != typeObjectSpecifier) {
  5164.         return errAEWrongDataType;
  5165.     }
  5166.  
  5167.     /* resolve the object specifier */
  5168.     myErr = AEResolve(theAEDesc, kAEIDoMinimum, &objDesc);
  5169.  
  5170.     /* hopefully it's the right type by now, but we'll give it a nudge */
  5171.     if (myErr==noErr) {
  5172.         myErr = AECoerceDesc(&objDesc, toType, result);
  5173.         myErr = AEDisposeDesc(&objDesc);
  5174.     }
  5175.  
  5176.     if (result->descriptorType!=toType) {
  5177.         /*DebugStr('COTA - Not of requested type');*/
  5178.     }
  5179.  
  5180.     return myErr;
  5181. }    /* CoerceObjToAnything */
  5182.  
  5183. /*******************************************************************************/
  5184.  
  5185. /*----------------------------------------------------------------------------------------------*/
  5186.  
  5187. /*now for the edition manager event handling code*/
  5188.  
  5189. pascal OSErr GetHandleFromEvent(const AppleEvent *theAppleEvent, SectionHandle *sectionH)
  5190. {
  5191.     DescType ignoreType;
  5192.     Size          ignoreSize;
  5193.  
  5194.     return
  5195.         AEGetKeyPtr(
  5196.             theAppleEvent,
  5197.             keyDirectObject,
  5198.             typeSectionH,
  5199.             &ignoreType,
  5200.             (Ptr)sectionH,
  5201.             sizeof(SectionHandle),
  5202.             &ignoreSize);
  5203. } /* GetHandleFromEvent */
  5204.  
  5205. /*----------------------------------------------------------------------------------------------*/
  5206. pascal OSErr DoReadSection(const AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  5207. {
  5208. #pragma unused (reply, refCon)
  5209.  
  5210.     OSErr         err;
  5211.     SectionHandle sectionH;
  5212.  
  5213.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5214.     if (IsRegisteredSection(sectionH)==noErr)
  5215.         ReadAnEdition(sectionH);
  5216.     return err;
  5217. } /* DoReadSection */
  5218.  
  5219. /*----------------------------------------------------------------------------------------------*/
  5220. pascal OSErr DoWriteSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5221. {
  5222. #pragma unused (reply, refCon)
  5223.  
  5224.     OSErr         err;
  5225.     SectionHandle sectionH;
  5226.  
  5227.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5228.     if (IsRegisteredSection(sectionH) == noErr)
  5229.         WriteAnEdition(sectionH);
  5230.  
  5231.     return err;
  5232. } /* DoWriteSection */
  5233.  
  5234. /*----------------------------------------------------------------------------------------------*/
  5235. pascal OSErr DoScrollSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5236. {
  5237. #pragma unused (reply, refCon)
  5238.  
  5239.     OSErr         err;
  5240.     SectionHandle sectionH;
  5241.     SectHandle    aSectHandle;
  5242.  
  5243.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5244.     /*get at the sectHandle*/
  5245.     aSectHandle = (SectHandle)GetERefCon(sectionH);
  5246.     TESetSelect((**aSectHandle).fStart, (**aSectHandle).fEnd, ((**aSectHandle).fDocument)->theText);
  5247.     ShowSelect((**aSectHandle).fDocument);
  5248.     return err;
  5249. }
  5250.  
  5251. /*----------------------------------------------------------------------------------------------*/
  5252. pascal OSErr DoCancelSection(const AppleEvent *theAppleEvent, AppleEvent *reply, long refCon)
  5253. {
  5254. #pragma unused (reply, refCon)
  5255.  
  5256.     OSErr         err;
  5257.     SectionHandle sectionH;
  5258.     SectHandle    aSectHandle;
  5259.  
  5260.     err = GetHandleFromEvent(theAppleEvent, §ionH);
  5261.     aSectHandle = (SectHandle)GetERefCon(sectionH);
  5262.     err = UnRegisterSection(sectionH);
  5263.     DeleteASection(aSectHandle, (**aSectHandle).fDocument);
  5264.     return noErr;
  5265. } /* DoCancelSection */
  5266.  
  5267. #endif
  5268.  
  5269. pascal OSErr Text2FSSpec(
  5270.     DescType type, Ptr path, Size size, 
  5271.     DescType to, long refCon, AEDesc * result)
  5272. {
  5273.     OSErr            err;
  5274.     char            file[256];
  5275.     FSSpec        spec;
  5276.     CInfoPBRec    info;
  5277.     
  5278.     if (size > 255)
  5279.         return errAECoercionFail;
  5280.         
  5281.     memcpy(file, path, size);
  5282.     file[size] = 0;
  5283.     
  5284.     if (err = Path2FSSpec(file, &spec))
  5285.         return err;
  5286.     if (err = FSpCatInfo(&spec, &info))
  5287.         return err;
  5288.     
  5289.     return AECreateDesc(typeFSS, (Ptr) &spec, sizeof(FSSpec), result);
  5290. }
  5291.  
  5292. /* -----------------------------------------------------------------------
  5293.         Name:             InitAppleEvents
  5294.         Purpose:        Initialise the AppleEvent despatch table
  5295.      -----------------------------------------------------------------------**/
  5296.  
  5297. #pragma segment Main
  5298.  
  5299. #define noRefCon -1
  5300.  
  5301. pascal void InitAppleEvents(void)
  5302. {
  5303.     OSErr aevtErr;
  5304.  
  5305.      gBigBrother = 0;
  5306.     gCharsInBuffer = 0;
  5307.     gTypingBuffer  = (char *)NewPtr(32000);
  5308.     gTypingTargetObject.dataHandle = 0;
  5309.  
  5310.     /*set up the dispatch table for the four standard apple events*/
  5311.  
  5312.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, (EventHandlerProcPtr)DoOpenApp, noRefCon, false) ;
  5313.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments,   (EventHandlerProcPtr)DoOpenDocument, noRefCon, false) ;
  5314.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments,  (EventHandlerProcPtr)DoPrintDocuments, noRefCon, false) ;
  5315.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, (EventHandlerProcPtr)MyQuit, noRefCon, false) ;
  5316.  
  5317. #ifndef RUNTIME
  5318.     aevtErr = AEInstallEventHandler( MPAppSig,           kAEOpenDocuments,   (EventHandlerProcPtr)DoOpenDocument, 1, false) ;
  5319.  
  5320.     /* set up the dispatch table for the core AppleEvents for text */
  5321.  
  5322.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEDelete, (EventHandlerProcPtr)DoDeleteEdit,noRefCon, false);
  5323.  
  5324.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECut,    (EventHandlerProcPtr)DoCutEdit,   noRefCon, false);
  5325.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECopy,   (EventHandlerProcPtr)DoCopyEdit,  noRefCon, false);
  5326.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEPaste,  (EventHandlerProcPtr)DoPasteEdit, noRefCon, false);
  5327.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAESetData,(EventHandlerProcPtr)DoSetData,   noRefCon, false);
  5328.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEGetData,(EventHandlerProcPtr)DoGetData,   noRefCon, false);
  5329.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEGetDataSize,(EventHandlerProcPtr)DoGetDataSize,   noRefCon, false);
  5330.  
  5331.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAECountElements,   (EventHandlerProcPtr)HandleNumberOfElements,   noRefCon, false);
  5332.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAECreateElement,   (EventHandlerProcPtr)DoNewElement,   noRefCon, false);
  5333.     aevtErr = AEInstallEventHandler( kAECoreSuite, kAEDoObjectsExist,  (EventHandlerProcPtr)DoIsThereA,   noRefCon, false);
  5334.  
  5335.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAEClose,  (EventHandlerProcPtr)DoCloseWindow,noRefCon, false);
  5336.     aevtErr = AEInstallEventHandler( kAECoreSuite,     kAESave,   (EventHandlerProcPtr)DoSaveWindow,noRefCon, false);
  5337.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAERevert, (EventHandlerProcPtr)DoRevertWindow,noRefCon, false);
  5338.  
  5339.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAECreatePublisher,    (EventHandlerProcPtr)HandleCreatePub, noRefCon, false);
  5340.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEMakeObjectsVisible, (EventHandlerProcPtr)HandleShowSelection,   noRefCon, false);
  5341.  
  5342.     aevtErr = AEInstallEventHandler( kAEMiscStandards, kAEDoScript,           (EventHandlerProcPtr)DoScript, noRefCon, false);
  5343.  
  5344.     /* Now look for recording notifications */
  5345.  
  5346.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEStartedRecording, (EventHandlerProcPtr)HandleStartRecording, noRefCon, false);
  5347.     aevtErr = AEInstallEventHandler( kCoreEventClass, kAEStoppedRecording, (EventHandlerProcPtr)HandleStopRecording, noRefCon, false);
  5348.  
  5349.     /* Now Put in the required object accessors */
  5350.  
  5351.     aevtErr = AESetObjectCallbacks(nil,MyCountProc,nil,nil,nil,nil,nil);
  5352.  
  5353.     aevtErr = AEInstallObjectAccessor(cWindow,      typeNull,   WindowFromNullAccessor,  0,false);
  5354.     aevtErr = AEInstallObjectAccessor(cWindow,      typeMyAppl, WindowFromNullAccessor,  0,false);
  5355.  
  5356.     aevtErr = AEInstallObjectAccessor(cApplication, typeNull,   ApplicationFromNullAccessor,  0,false);
  5357.     aevtErr = AEInstallObjectAccessor(cProperty,    typeMyAppl, PropertyFromApplAccessor,0,false);
  5358.  
  5359.     aevtErr = AEInstallObjectAccessor(cChar,             typeMyWndw,TextElemFromWndwAccessor,0,false);
  5360.     aevtErr = AEInstallObjectAccessor(cSpot,             typeMyWndw,TextElemFromWndwAccessor,0,false);
  5361.     aevtErr = AEInstallObjectAccessor(cWord,             typeMyWndw,TextElemFromWndwAccessor,0,false);
  5362.     aevtErr = AEInstallObjectAccessor(cLine,             typeMyWndw,TextElemFromWndwAccessor,0,false);
  5363.     aevtErr = AEInstallObjectAccessor(cText,             typeMyWndw,TextElemFromWndwAccessor,0,false);
  5364.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyWndw,PropertyFromWndwAccessor,0,false);
  5365.  
  5366.     aevtErr = AEInstallObjectAccessor(cProperty,          typeMyText,PropertyFromTextAccessor,0,false);
  5367.     aevtErr = AEInstallObjectAccessor(cChar,           typeMyText,TextElemFromTextAccessor,0,false);
  5368.     aevtErr = AEInstallObjectAccessor(cWord,           typeMyText,TextElemFromTextAccessor,0,false);
  5369.     aevtErr = AEInstallObjectAccessor(cSpot,           typeMyText,TextElemFromTextAccessor,0,false);
  5370.     aevtErr = AEInstallObjectAccessor(cLine,           typeMyText,TextElemFromTextAccessor,0,false);
  5371.  
  5372.     aevtErr = AEInstallObjectAccessor(cMenu,           typeNull,       MenuFromNullAccessor,    0,false);
  5373.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyMenu,     PropertyFromMenuAccessor,0,false);
  5374.     aevtErr = AEInstallObjectAccessor(cProperty,        typeMyMenuItem, PropertyFromMenuItemAccessor,0,false);
  5375.     aevtErr = AEInstallObjectAccessor(cMenuItem,        typeMyMenu,     MenuItemFromMenuAccessor,0,false);
  5376.     /* Now the coercion handlers */
  5377.  
  5378.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyAppl,      (ProcPtr)CoerceObjToAnything,0,true,false);
  5379.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyWndw,      (ProcPtr)CoerceObjToAnything,0,true,false);
  5380.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyText,      (ProcPtr)CoerceObjToAnything,0,true,false);
  5381.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyTextProp,  (ProcPtr)CoerceObjToAnything,0,true,false);
  5382.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyWindowProp,(ProcPtr)CoerceObjToAnything,0,true,false);
  5383.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyApplProp,  (ProcPtr)CoerceObjToAnything,0,true,false);
  5384.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenu,      (ProcPtr)CoerceObjToAnything,0,true,false);
  5385.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenuProp,  (ProcPtr)CoerceObjToAnything,0,true,false);
  5386.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyMenuItem,  (ProcPtr)CoerceObjToAnything,0,true,false);
  5387.     aevtErr = AEInstallCoercionHandler(typeObjectSpecifier,typeMyItemProp,  (ProcPtr)CoerceObjToAnything,0,true,false);
  5388.  
  5389.     aevtErr = AEInstallCoercionHandler(typeChar,typeFSS,  (ProcPtr)Text2FSSpec,0,false,false);
  5390.         /*now install the appropriate edition manager events*/
  5391.  
  5392.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionReadMsgID,   (EventHandlerProcPtr)DoReadSection, noRefCon, false) ;
  5393.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionWriteMsgID,  (EventHandlerProcPtr)DoWriteSection, noRefCon, false) ;
  5394.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionScrollMsgID, (EventHandlerProcPtr)DoScrollSection, noRefCon, false) ;
  5395.     aevtErr = AEInstallEventHandler( sectionEventMsgClass, sectionCancelMsgID, (EventHandlerProcPtr)DoCancelSection, noRefCon, false) ;
  5396. #endif
  5397. } /* InitAppleEvents */
  5398.